Major improvements: Fix download limits, enhance license display, fix software filenames
🔧 Bug Fixes: - Fixed download limits defaulting to 5 instead of 0 for unlimited downloads - Fixed software license filename sanitization (spaces→dashes, dots→underscores, proper .zip extension) - Software downloads now show as "Test-Plugin-v2-2-0.zip" instead of "Test Plugin v2.2.0" ✨ UI/UX Enhancements: - Redesigned license key display to span full table width with FontAwesome copy icons - Added responsive CSS styling for license key rows - Integrated FontAwesome CDN for modern copy icons 🏗️ Architecture Improvements: - Added comprehensive filename sanitization in both download handler and API paths - Enhanced software license product handling for local package files - Improved error handling and logging throughout download processes 📦 Infrastructure: - Added Gitea workflows for automated releases on push to main - Created comprehensive .gitignore excluding test files and browser automation - Updated documentation with all recent improvements and technical insights 🔍 Technical Details: - Software license products served from wp-content/uploads/wpdd-packages/ - Download flow: token → process_download_by_token() → process_download() → deliver_file() - Dual path coverage for both API downloads and regular file delivery - Version placeholder system for automated deployment 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -466,4 +466,63 @@
|
||||
.wpdd-login-required a {
|
||||
color: #856404;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* License Key Display */
|
||||
.wpdd-license-row {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.wpdd-license-cell {
|
||||
padding: 8px 12px !important;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.wpdd-license-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wpdd-license-info small {
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wpdd-license-key {
|
||||
background: #f8f9fa;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
border: 1px solid #ddd;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.wpdd-copy-license {
|
||||
background: #0073aa;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
transition: background 0.3s;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.wpdd-copy-license:hover {
|
||||
background: #005a87;
|
||||
}
|
||||
|
||||
.wpdd-copy-license i {
|
||||
font-size: 11px;
|
||||
}
|
31
assets/js/admin-order-manager.js
Normal file
31
assets/js/admin-order-manager.js
Normal file
@@ -0,0 +1,31 @@
|
||||
jQuery(document).ready(function($) {
|
||||
// Handle cancel order button clicks
|
||||
$('.wpdd-cancel-btn').on('click', function(e) {
|
||||
if (!confirm(wpdd_order_manager.confirm_cancel)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Handle refund order button clicks
|
||||
$('.wpdd-refund-btn').on('click', function(e) {
|
||||
if (!confirm(wpdd_order_manager.confirm_refund)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Handle release earnings button clicks
|
||||
$('.wpdd-release-btn').on('click', function(e) {
|
||||
if (!confirm(wpdd_order_manager.confirm_release)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-submit form when filter values change (optional convenience feature)
|
||||
$('#status, #creator').on('change', function() {
|
||||
// Uncomment the next line if you want auto-submit on filter change
|
||||
// $(this).closest('form').submit();
|
||||
});
|
||||
});
|
@@ -1,4 +1,39 @@
|
||||
jQuery(document).ready(function($) {
|
||||
// Format currency
|
||||
function formatCurrency(amount) {
|
||||
return '$' + parseFloat(amount).toFixed(2);
|
||||
}
|
||||
|
||||
// Handle creator selection for manual payout
|
||||
$('#creator_id').on('change', function() {
|
||||
var selectedOption = $(this).find('option:selected');
|
||||
var balance = selectedOption.data('balance');
|
||||
var balanceDisplay = $('#creator_balance_display');
|
||||
var balanceAmount = $('#creator_balance_amount');
|
||||
|
||||
if ($(this).val() && balance !== undefined) {
|
||||
balanceAmount.text(formatCurrency(balance));
|
||||
balanceDisplay.show();
|
||||
} else {
|
||||
balanceDisplay.hide();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle creator selection for balance adjustment
|
||||
$('#adj_creator_id').on('change', function() {
|
||||
var selectedOption = $(this).find('option:selected');
|
||||
var balance = selectedOption.data('balance');
|
||||
var balanceDisplay = $('#adj_creator_balance_display');
|
||||
var balanceAmount = $('#adj_creator_balance_amount');
|
||||
|
||||
if ($(this).val() && balance !== undefined) {
|
||||
balanceAmount.text(formatCurrency(balance));
|
||||
balanceDisplay.show();
|
||||
} else {
|
||||
balanceDisplay.hide();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle individual payout processing
|
||||
$('.wpdd-process-payout').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
@@ -10,6 +10,7 @@ jQuery(document).ready(function($) {
|
||||
this.initFileManager();
|
||||
this.initPriceToggle();
|
||||
this.initFormValidation();
|
||||
this.initProductSync();
|
||||
},
|
||||
|
||||
initFileManager: function() {
|
||||
@@ -324,6 +325,51 @@ jQuery(document).ready(function($) {
|
||||
$('.wpdd-settings-content').hide();
|
||||
$(target).show();
|
||||
});
|
||||
},
|
||||
|
||||
initProductSync: function() {
|
||||
// Handle software product sync
|
||||
$(document).on('click', '.wpdd-sync-product', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var productId = $button.data('product-id');
|
||||
var nonce = $button.data('nonce');
|
||||
|
||||
if (!productId || !nonce) {
|
||||
WPDD_Admin.showAdminNotice('Invalid sync request', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
$button.prop('disabled', true).text('Syncing...');
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'wpdd_sync_software_product',
|
||||
product_id: productId,
|
||||
nonce: nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
WPDD_Admin.showAdminNotice(response.message, 'success');
|
||||
// Reload the page to show updated file count
|
||||
setTimeout(function() {
|
||||
window.location.reload();
|
||||
}, 1500);
|
||||
} else {
|
||||
WPDD_Admin.showAdminNotice(response.message || 'Sync failed', 'error');
|
||||
$button.prop('disabled', false).text('Sync Files');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
WPDD_Admin.showAdminNotice('Sync request failed', 'error');
|
||||
$button.prop('disabled', false).text('Sync Files');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -27,6 +27,9 @@ jQuery(document).ready(function($) {
|
||||
|
||||
// Download status check
|
||||
$(document).on('click', '.wpdd-check-download', this.checkDownloadStatus);
|
||||
|
||||
// Copy license key
|
||||
$(document).on('click', '.wpdd-copy-license', this.copyLicenseKey);
|
||||
},
|
||||
|
||||
initProductCards: function() {
|
||||
@@ -358,6 +361,61 @@ jQuery(document).ready(function($) {
|
||||
|
||||
formatPrice: function(price) {
|
||||
return '$' + parseFloat(price).toFixed(2);
|
||||
},
|
||||
|
||||
copyLicenseKey: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var licenseKey = $button.data('license');
|
||||
|
||||
if (!licenseKey) {
|
||||
WPDD.showNotice('No license key to copy', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to use the modern clipboard API
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
navigator.clipboard.writeText(licenseKey).then(function() {
|
||||
WPDD.showNotice('License key copied to clipboard!', 'success');
|
||||
$button.text('Copied!');
|
||||
setTimeout(function() {
|
||||
$button.text('Copy');
|
||||
}, 2000);
|
||||
}).catch(function() {
|
||||
WPDD.fallbackCopyTextToClipboard(licenseKey, $button);
|
||||
});
|
||||
} else {
|
||||
WPDD.fallbackCopyTextToClipboard(licenseKey, $button);
|
||||
}
|
||||
},
|
||||
|
||||
fallbackCopyTextToClipboard: function(text, $button) {
|
||||
var textArea = document.createElement('textarea');
|
||||
textArea.value = text;
|
||||
textArea.style.position = 'fixed';
|
||||
textArea.style.left = '-999999px';
|
||||
textArea.style.top = '-999999px';
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
var successful = document.execCommand('copy');
|
||||
if (successful) {
|
||||
WPDD.showNotice('License key copied to clipboard!', 'success');
|
||||
$button.text('Copied!');
|
||||
setTimeout(function() {
|
||||
$button.text('Copy');
|
||||
}, 2000);
|
||||
} else {
|
||||
WPDD.showNotice('Failed to copy license key', 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
WPDD.showNotice('Failed to copy license key', 'error');
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user