You've already forked wc-licensed-product
Dashboard widget improvements and download counter feature (v0.3.7)
- Fixed: Dashboard widget "View All Licenses" link used wrong page slug - Fixed: Download links in customer account resulted in 404 errors - Removed: Redundant "Status Breakdown" section from dashboard widget - Changed: License Types section now uses card style layout - Added: Download counter for licensed product versions - Added: Download Statistics admin dashboard widget - Updated translations (356 strings) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,7 +55,7 @@ final class DashboardWidgetController
|
||||
public function renderWidget(): void
|
||||
{
|
||||
$stats = $this->licenseManager->getStatistics();
|
||||
$licensesUrl = admin_url('admin.php?page=wc-licensed-product-licenses');
|
||||
$licensesUrl = admin_url('admin.php?page=wc-licenses');
|
||||
?>
|
||||
<style>
|
||||
.wclp-widget-stats {
|
||||
@@ -96,40 +96,6 @@ final class DashboardWidgetController
|
||||
letter-spacing: 0.5px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.wclp-widget-divider {
|
||||
border-top: 1px solid #e2e4e7;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.wclp-status-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.wclp-status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wclp-status-badge.active {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
.wclp-status-badge.inactive {
|
||||
background: #e2e3e5;
|
||||
color: #383d41;
|
||||
}
|
||||
.wclp-status-badge.expired {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
.wclp-status-badge.revoked {
|
||||
background: #d6d8db;
|
||||
color: #1b1e21;
|
||||
}
|
||||
.wclp-widget-footer {
|
||||
margin-top: 16px;
|
||||
padding-top: 12px;
|
||||
@@ -160,61 +126,17 @@ final class DashboardWidgetController
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wclp-widget-divider"></div>
|
||||
|
||||
<h4 style="margin: 0 0 8px 0; font-size: 13px; color: #1d2327;">
|
||||
<?php esc_html_e('Status Breakdown', 'wc-licensed-product'); ?>
|
||||
</h4>
|
||||
<div class="wclp-status-list">
|
||||
<span class="wclp-status-badge active">
|
||||
<span class="dashicons dashicons-yes-alt" style="font-size: 14px; width: 14px; height: 14px;"></span>
|
||||
<?php printf(
|
||||
esc_html__('Active: %d', 'wc-licensed-product'),
|
||||
$stats['by_status'][License::STATUS_ACTIVE]
|
||||
); ?>
|
||||
</span>
|
||||
<span class="wclp-status-badge inactive">
|
||||
<span class="dashicons dashicons-marker" style="font-size: 14px; width: 14px; height: 14px;"></span>
|
||||
<?php printf(
|
||||
esc_html__('Inactive: %d', 'wc-licensed-product'),
|
||||
$stats['by_status'][License::STATUS_INACTIVE]
|
||||
); ?>
|
||||
</span>
|
||||
<span class="wclp-status-badge expired">
|
||||
<span class="dashicons dashicons-clock" style="font-size: 14px; width: 14px; height: 14px;"></span>
|
||||
<?php printf(
|
||||
esc_html__('Expired: %d', 'wc-licensed-product'),
|
||||
$stats['by_status'][License::STATUS_EXPIRED]
|
||||
); ?>
|
||||
</span>
|
||||
<span class="wclp-status-badge revoked">
|
||||
<span class="dashicons dashicons-dismiss" style="font-size: 14px; width: 14px; height: 14px;"></span>
|
||||
<?php printf(
|
||||
esc_html__('Revoked: %d', 'wc-licensed-product'),
|
||||
$stats['by_status'][License::STATUS_REVOKED]
|
||||
); ?>
|
||||
</span>
|
||||
<div class="wclp-widget-stats">
|
||||
<div class="wclp-stat-card">
|
||||
<div class="wclp-stat-number"><?php echo esc_html(number_format_i18n($stats['expiring'])); ?></div>
|
||||
<div class="wclp-stat-label"><?php esc_html_e('Time-limited', 'wc-licensed-product'); ?></div>
|
||||
</div>
|
||||
<div class="wclp-stat-card">
|
||||
<div class="wclp-stat-number"><?php echo esc_html(number_format_i18n($stats['lifetime'])); ?></div>
|
||||
<div class="wclp-stat-label"><?php esc_html_e('Lifetime', 'wc-licensed-product'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wclp-widget-divider"></div>
|
||||
|
||||
<h4 style="margin: 0 0 8px 0; font-size: 13px; color: #1d2327;">
|
||||
<?php esc_html_e('License Types', 'wc-licensed-product'); ?>
|
||||
</h4>
|
||||
<p style="margin: 0; font-size: 13px; color: #646970;">
|
||||
<span class="dashicons dashicons-calendar-alt" style="font-size: 14px; width: 14px; height: 14px; vertical-align: text-bottom;"></span>
|
||||
<?php printf(
|
||||
esc_html__('Time-limited: %d', 'wc-licensed-product'),
|
||||
$stats['expiring']
|
||||
); ?>
|
||||
|
|
||||
<span class="dashicons dashicons-infinity" style="font-size: 14px; width: 14px; height: 14px; vertical-align: text-bottom;"></span>
|
||||
<?php printf(
|
||||
esc_html__('Lifetime: %d', 'wc-licensed-product'),
|
||||
$stats['lifetime']
|
||||
); ?>
|
||||
</p>
|
||||
|
||||
<div class="wclp-widget-footer">
|
||||
<a href="<?php echo esc_url($licensesUrl); ?>" class="button button-secondary">
|
||||
<?php esc_html_e('View All Licenses', 'wc-licensed-product'); ?>
|
||||
|
||||
184
src/Admin/DownloadWidgetController.php
Normal file
184
src/Admin/DownloadWidgetController.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* Download Statistics Widget Controller
|
||||
*
|
||||
* @package Jeremias\WcLicensedProduct\Admin
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jeremias\WcLicensedProduct\Admin;
|
||||
|
||||
use Jeremias\WcLicensedProduct\Product\VersionManager;
|
||||
|
||||
/**
|
||||
* Handles the WordPress admin dashboard widget for download statistics
|
||||
*/
|
||||
final class DownloadWidgetController
|
||||
{
|
||||
private VersionManager $versionManager;
|
||||
|
||||
public function __construct(VersionManager $versionManager)
|
||||
{
|
||||
$this->versionManager = $versionManager;
|
||||
$this->registerHooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register WordPress hooks
|
||||
*/
|
||||
private function registerHooks(): void
|
||||
{
|
||||
add_action('wp_dashboard_setup', [$this, 'registerDashboardWidget']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the dashboard widget
|
||||
*/
|
||||
public function registerDashboardWidget(): void
|
||||
{
|
||||
if (!current_user_can('manage_woocommerce')) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_add_dashboard_widget(
|
||||
'wclp_download_statistics',
|
||||
__('Download Statistics', 'wc-licensed-product'),
|
||||
[$this, 'renderWidget']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the dashboard widget content
|
||||
*/
|
||||
public function renderWidget(): void
|
||||
{
|
||||
$stats = $this->versionManager->getDownloadStatistics();
|
||||
?>
|
||||
<style>
|
||||
.wclp-download-widget-stats {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.wclp-download-stat-card {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e2e4e7;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
border-left: 3px solid #2271b1;
|
||||
}
|
||||
.wclp-download-stat-number {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #1d2327;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.wclp-download-stat-label {
|
||||
font-size: 12px;
|
||||
color: #646970;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.wclp-download-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.wclp-download-list li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #e2e4e7;
|
||||
}
|
||||
.wclp-download-list li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.wclp-download-list .product-name {
|
||||
font-weight: 500;
|
||||
color: #1d2327;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-right: 12px;
|
||||
}
|
||||
.wclp-download-list .version-info {
|
||||
font-size: 12px;
|
||||
color: #646970;
|
||||
}
|
||||
.wclp-download-list .download-count {
|
||||
background: #e7f5ff;
|
||||
color: #0a4b78;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.wclp-download-section-title {
|
||||
margin: 16px 0 8px 0;
|
||||
font-size: 13px;
|
||||
color: #1d2327;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wclp-no-downloads {
|
||||
color: #646970;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: 12px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="wclp-download-widget-stats">
|
||||
<div class="wclp-download-stat-card">
|
||||
<div class="wclp-download-stat-number"><?php echo esc_html(number_format_i18n($stats['total'])); ?></div>
|
||||
<div class="wclp-download-stat-label"><?php esc_html_e('Total Downloads', 'wc-licensed-product'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="wclp-download-section-title">
|
||||
<?php esc_html_e('Top Products', 'wc-licensed-product'); ?>
|
||||
</h4>
|
||||
<?php if (!empty($stats['by_product'])): ?>
|
||||
<ul class="wclp-download-list">
|
||||
<?php foreach (array_slice($stats['by_product'], 0, 5) as $product): ?>
|
||||
<li>
|
||||
<span class="product-name"><?php echo esc_html($product['product_name']); ?></span>
|
||||
<span class="download-count">
|
||||
<?php echo esc_html(number_format_i18n($product['downloads'])); ?>
|
||||
</span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else: ?>
|
||||
<p class="wclp-no-downloads"><?php esc_html_e('No downloads yet', 'wc-licensed-product'); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<h4 class="wclp-download-section-title">
|
||||
<?php esc_html_e('Top Versions', 'wc-licensed-product'); ?>
|
||||
</h4>
|
||||
<?php if (!empty($stats['by_version'])): ?>
|
||||
<ul class="wclp-download-list">
|
||||
<?php foreach (array_slice($stats['by_version'], 0, 5) as $version): ?>
|
||||
<li>
|
||||
<span class="product-name">
|
||||
<?php echo esc_html($version['product_name']); ?>
|
||||
<span class="version-info">v<?php echo esc_html($version['version']); ?></span>
|
||||
</span>
|
||||
<span class="download-count">
|
||||
<?php echo esc_html(number_format_i18n($version['downloads'])); ?>
|
||||
</span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else: ?>
|
||||
<p class="wclp-no-downloads"><?php esc_html_e('No downloads yet', 'wc-licensed-product'); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user