Major improvements: Fix download limits, enhance license display, fix software filenames
Some checks failed
Create Release / build (push) Failing after 3s

🔧 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 6d86d5ef4f
commit 4731637f33
28 changed files with 3709 additions and 156 deletions

View File

@@ -92,7 +92,13 @@ class WPDD_Admin_Payouts {
</div>
<?php elseif ($_GET['message'] === 'error') : ?>
<div class="notice notice-error is-dismissible">
<p><?php _e('Error processing payout. Please try again.', 'wp-digital-download'); ?></p>
<p>
<?php _e('Error processing payout:', 'wp-digital-download'); ?>
<?php
$error_detail = isset($_GET['error_detail']) ? sanitize_text_field(urldecode($_GET['error_detail'])) : '';
echo $error_detail ? '<strong>' . esc_html($error_detail) . '</strong>' : __('Unknown error occurred. Please try again.', 'wp-digital-download');
?>
</p>
</div>
<?php elseif ($_GET['message'] === 'balance_adjusted') : ?>
<div class="notice notice-success is-dismissible">
@@ -166,19 +172,26 @@ class WPDD_Admin_Payouts {
<tr>
<th><label for="creator_id"><?php _e('Creator', 'wp-digital-download'); ?></label></th>
<td>
<select name="creator_id" id="creator_id" required style="width: 100%;">
<select name="creator_id" id="creator_id" class="wpdd-creator-select" required style="width: 100%;">
<option value=""><?php _e('Select Creator', 'wp-digital-download'); ?></option>
<?php
$all_creators = get_users(array('role' => 'wpdd_creator'));
foreach ($all_creators as $creator) :
$paypal_email = get_user_meta($creator->ID, 'wpdd_paypal_email', true);
$balance = WPDD_Creator::get_creator_balance($creator->ID);
?>
<option value="<?php echo esc_attr($creator->ID); ?>" <?php echo empty($paypal_email) ? 'disabled' : ''; ?>>
<option value="<?php echo esc_attr($creator->ID); ?>"
data-balance="<?php echo esc_attr($balance); ?>"
data-paypal="<?php echo esc_attr($paypal_email); ?>"
<?php echo empty($paypal_email) ? 'disabled' : ''; ?>>
<?php echo esc_html($creator->display_name); ?>
<?php echo empty($paypal_email) ? ' (' . __('No PayPal email', 'wp-digital-download') . ')' : ' (' . esc_html($paypal_email) . ')'; ?>
</option>
<?php endforeach; ?>
</select>
<div id="creator_balance_display" style="margin-top: 10px; display: none;">
<strong><?php _e('Current Balance:', 'wp-digital-download'); ?></strong> <span id="creator_balance_amount"></span>
</div>
</td>
</tr>
<tr>
@@ -217,14 +230,19 @@ class WPDD_Admin_Payouts {
<tr>
<th><label for="adj_creator_id"><?php _e('Creator', 'wp-digital-download'); ?></label></th>
<td>
<select name="creator_id" id="adj_creator_id" required style="width: 100%;">
<select name="creator_id" id="adj_creator_id" class="wpdd-creator-select" required style="width: 100%;">
<option value=""><?php _e('Select Creator', 'wp-digital-download'); ?></option>
<?php foreach ($all_creators as $creator) : ?>
<option value="<?php echo esc_attr($creator->ID); ?>">
<?php foreach ($all_creators as $creator) :
$balance = WPDD_Creator::get_creator_balance($creator->ID);
?>
<option value="<?php echo esc_attr($creator->ID); ?>" data-balance="<?php echo esc_attr($balance); ?>">
<?php echo esc_html($creator->display_name); ?>
</option>
<?php endforeach; ?>
</select>
<div id="adj_creator_balance_display" style="margin-top: 10px; display: none;">
<strong><?php _e('Current Balance:', 'wp-digital-download'); ?></strong> <span id="adj_creator_balance_amount"></span>
</div>
</td>
</tr>
<tr>
@@ -497,10 +515,11 @@ class WPDD_Admin_Payouts {
$result = self::create_payout($creator_id);
if ($result) {
if ($result['success']) {
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=success'));
} else {
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=error'));
$error_message = urlencode($result['error'] ?? 'Unknown error occurred');
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=error&error_detail=' . $error_message));
}
exit;
}
@@ -543,11 +562,28 @@ class WPDD_Admin_Payouts {
public static function create_payout($creator_id, $method = 'manual') {
global $wpdb;
// Validate creator
$creator = get_userdata($creator_id);
if (!$creator) {
return array('success' => false, 'error' => 'Creator not found');
}
$balance = WPDD_Creator::get_creator_balance($creator_id);
$paypal_email = get_user_meta($creator_id, 'wpdd_paypal_email', true);
if ($balance <= 0 || empty($paypal_email)) {
return false;
if ($balance <= 0) {
return array('success' => false, 'error' => 'Creator has zero balance to payout');
}
if (empty($paypal_email)) {
return array('success' => false, 'error' => 'Creator has no PayPal email configured');
}
// Validate PayPal credentials are configured
$client_id = get_option('wpdd_paypal_client_id');
$secret = get_option('wpdd_paypal_secret');
if (empty($client_id) || empty($secret)) {
return array('success' => false, 'error' => 'PayPal credentials not configured in settings');
}
$currency = get_option('wpdd_currency', 'USD');
@@ -571,6 +607,10 @@ class WPDD_Admin_Payouts {
$payout_id = $wpdb->insert_id;
if (!$payout_id) {
return array('success' => false, 'error' => 'Failed to create payout record in database');
}
// Try to process via PayPal API
$result = WPDD_PayPal_Payouts::process_payout($payout_id);
@@ -588,10 +628,25 @@ class WPDD_Admin_Payouts {
array('%d')
);
// Mark all available earnings for this creator as paid
$wpdb->update(
$wpdb->prefix . 'wpdd_creator_earnings',
array(
'payout_id' => $payout_id,
'payout_status' => 'paid'
),
array(
'creator_id' => $creator_id,
'payout_status' => 'available'
),
array('%d', '%s'),
array('%d', '%s')
);
// Reset creator balance
update_user_meta($creator_id, 'wpdd_creator_balance', 0);
return true;
return array('success' => true, 'message' => 'Payout processed successfully');
} else {
// Update with error
$wpdb->update(
@@ -605,7 +660,7 @@ class WPDD_Admin_Payouts {
array('%d')
);
return false;
return array('success' => false, 'error' => $result['error'] ?? 'PayPal payout processing failed');
}
}
@@ -813,7 +868,7 @@ class WPDD_Admin_Payouts {
}
// Get current balance
$current_balance = floatval(get_user_meta($creator_id, 'wpdd_balance', true));
$current_balance = floatval(get_user_meta($creator_id, 'wpdd_creator_balance', true));
// Calculate new balance
if ($adjustment_type === 'add') {
@@ -823,7 +878,7 @@ class WPDD_Admin_Payouts {
}
// Update the balance
update_user_meta($creator_id, 'wpdd_balance', $new_balance);
update_user_meta($creator_id, 'wpdd_creator_balance', $new_balance);
// Create a record of this adjustment
global $wpdb;