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:
2025-09-09 19:16:57 -07:00
parent ce48f1615f
commit a160fe3964
28 changed files with 3709 additions and 156 deletions

View File

@@ -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;
}

View 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();
});
});

View File

@@ -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();

View File

@@ -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');
}
});
});
}
};

View File

@@ -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);
}
};