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

@@ -14,6 +14,8 @@ class WPDD_Admin {
add_action('pre_get_posts', array(__CLASS__, 'sort_products_by_column'));
add_action('pre_get_posts', array(__CLASS__, 'filter_creator_products'));
add_action('admin_init', array(__CLASS__, 'handle_admin_actions'));
add_action('wp_ajax_wpdd_sync_software_product', array(__CLASS__, 'handle_sync_software_product'));
add_action('wp_ajax_wpdd_regenerate_licenses', array(__CLASS__, 'handle_regenerate_licenses'));
// Initialize admin payouts
if (class_exists('WPDD_Admin_Payouts')) {
@@ -145,7 +147,17 @@ class WPDD_Admin {
case 'wpdd_files':
$files = get_post_meta($post_id, '_wpdd_files', true);
$count = is_array($files) ? count($files) : 0;
$product_type = get_post_meta($post_id, '_wpdd_product_type', true);
echo $count;
// Add sync button for software license products with no files
if ($product_type === 'software_license' && $count === 0) {
$nonce = wp_create_nonce('wpdd_sync_product_' . $post_id);
echo '<br><button type="button" class="button button-small wpdd-sync-product" data-product-id="' . $post_id . '" data-nonce="' . $nonce . '">';
echo __('Sync Files', 'wp-digital-download');
echo '</button>';
}
break;
}
}
@@ -1232,4 +1244,64 @@ class WPDD_Admin {
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-creator-payouts&message=payout_requested'));
exit;
}
public static function handle_sync_software_product() {
if (!current_user_can('edit_wpdd_products')) {
wp_die('Unauthorized');
}
if (!isset($_POST['product_id']) || !wp_verify_nonce($_POST['nonce'], 'wpdd_sync_product_' . $_POST['product_id'])) {
wp_die('Invalid nonce');
}
$product_id = intval($_POST['product_id']);
if (!class_exists('WPDD_API')) {
require_once WPDD_PLUGIN_PATH . 'includes/class-wpdd-api.php';
}
$result = WPDD_API::sync_software_product($product_id, true);
wp_send_json($result);
}
public static function handle_regenerate_licenses() {
if (!current_user_can('manage_options')) {
wp_die('Unauthorized');
}
if (!wp_verify_nonce($_POST['nonce'], 'wpdd_regenerate_licenses')) {
wp_die('Invalid nonce');
}
global $wpdb;
// Find completed orders for software license products that don't have license keys
$orders = $wpdb->get_results("
SELECT o.*, pm.meta_value as product_type
FROM {$wpdb->prefix}wpdd_orders o
LEFT JOIN {$wpdb->postmeta} pm ON o.product_id = pm.post_id AND pm.meta_key = '_wpdd_product_type'
LEFT JOIN {$wpdb->prefix}wpdd_licenses l ON o.id = l.order_id
WHERE o.status = 'completed'
AND pm.meta_value = 'software_license'
AND l.license_key IS NULL
");
$generated = 0;
foreach ($orders as $order) {
if (class_exists('WPDD_License_Manager')) {
$license_key = WPDD_License_Manager::create_license($order->id);
if ($license_key) {
$generated++;
}
}
}
wp_send_json(array(
'success' => true,
'message' => sprintf('Generated %d license keys for existing orders.', $generated),
'generated' => $generated
));
}
}