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:
189
includes/class-wpdd-earnings-processor.php
Normal file
189
includes/class-wpdd-earnings-processor.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WPDD_Earnings_Processor {
|
||||
|
||||
public static function init() {
|
||||
// Schedule the cron job
|
||||
add_action('wp', array(__CLASS__, 'schedule_earnings_processing'));
|
||||
add_action('wpdd_process_pending_earnings', array(__CLASS__, 'process_pending_earnings'));
|
||||
|
||||
// Hook to plugin activation/deactivation
|
||||
register_activation_hook(WPDD_PLUGIN_PATH . 'wp-digital-download.php', array(__CLASS__, 'schedule_earnings_processing'));
|
||||
register_deactivation_hook(WPDD_PLUGIN_PATH . 'wp-digital-download.php', array(__CLASS__, 'clear_scheduled_earnings_processing'));
|
||||
}
|
||||
|
||||
public static function schedule_earnings_processing() {
|
||||
if (!wp_next_scheduled('wpdd_process_pending_earnings')) {
|
||||
// Run every hour to check for earnings that should be made available
|
||||
wp_schedule_event(time(), 'hourly', 'wpdd_process_pending_earnings');
|
||||
}
|
||||
}
|
||||
|
||||
public static function clear_scheduled_earnings_processing() {
|
||||
wp_clear_scheduled_hook('wpdd_process_pending_earnings');
|
||||
}
|
||||
|
||||
public static function process_pending_earnings() {
|
||||
global $wpdb;
|
||||
|
||||
// Find all earnings that are pending and past their available_at date
|
||||
$pending_earnings = $wpdb->get_results(
|
||||
"SELECT * FROM {$wpdb->prefix}wpdd_creator_earnings
|
||||
WHERE payout_status = 'pending'
|
||||
AND available_at <= NOW()
|
||||
AND available_at IS NOT NULL"
|
||||
);
|
||||
|
||||
if (empty($pending_earnings)) {
|
||||
return; // Nothing to process
|
||||
}
|
||||
|
||||
// Update all pending earnings to available
|
||||
$updated = $wpdb->query(
|
||||
"UPDATE {$wpdb->prefix}wpdd_creator_earnings
|
||||
SET payout_status = 'available'
|
||||
WHERE payout_status = 'pending'
|
||||
AND available_at <= NOW()
|
||||
AND available_at IS NOT NULL"
|
||||
);
|
||||
|
||||
if ($updated > 0) {
|
||||
// Log the processing
|
||||
error_log("WPDD: Processed $updated pending earnings to available status");
|
||||
|
||||
// Update creator balances for affected creators
|
||||
$affected_creators = $wpdb->get_col(
|
||||
"SELECT DISTINCT creator_id
|
||||
FROM {$wpdb->prefix}wpdd_creator_earnings
|
||||
WHERE payout_status = 'available'
|
||||
AND available_at <= NOW()"
|
||||
);
|
||||
|
||||
foreach ($affected_creators as $creator_id) {
|
||||
// Trigger balance recalculation
|
||||
$current_balance = WPDD_Creator::get_creator_balance($creator_id);
|
||||
update_user_meta($creator_id, 'wpdd_creator_balance', $current_balance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually process a specific earning (for admin override)
|
||||
*/
|
||||
public static function release_earning_immediately($earning_id) {
|
||||
global $wpdb;
|
||||
|
||||
$result = $wpdb->update(
|
||||
$wpdb->prefix . 'wpdd_creator_earnings',
|
||||
array(
|
||||
'payout_status' => 'available',
|
||||
'available_at' => current_time('mysql')
|
||||
),
|
||||
array(
|
||||
'id' => $earning_id,
|
||||
'payout_status' => 'pending'
|
||||
),
|
||||
array('%s', '%s'),
|
||||
array('%d', '%s')
|
||||
);
|
||||
|
||||
if ($result) {
|
||||
// Get the creator and update their balance
|
||||
$earning = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT creator_id FROM {$wpdb->prefix}wpdd_creator_earnings WHERE id = %d",
|
||||
$earning_id
|
||||
));
|
||||
|
||||
if ($earning) {
|
||||
$current_balance = WPDD_Creator::get_creator_balance($earning->creator_id);
|
||||
update_user_meta($earning->creator_id, 'wpdd_creator_balance', $current_balance);
|
||||
}
|
||||
}
|
||||
|
||||
return $result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel/refund a specific earning (for order cancellations)
|
||||
*/
|
||||
public static function cancel_earning($earning_id, $reason = 'Order cancelled/refunded') {
|
||||
global $wpdb;
|
||||
|
||||
// Get the earning details
|
||||
$earning = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}wpdd_creator_earnings WHERE id = %d",
|
||||
$earning_id
|
||||
));
|
||||
|
||||
if (!$earning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only cancel if not already paid out
|
||||
if ($earning->payout_status === 'paid') {
|
||||
return false; // Cannot cancel paid earnings
|
||||
}
|
||||
|
||||
// Update to cancelled status
|
||||
$result = $wpdb->update(
|
||||
$wpdb->prefix . 'wpdd_creator_earnings',
|
||||
array(
|
||||
'payout_status' => 'cancelled',
|
||||
'available_at' => null
|
||||
),
|
||||
array('id' => $earning_id),
|
||||
array('%s', '%s'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if ($result) {
|
||||
// Log the cancellation
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'wpdd_balance_adjustments',
|
||||
array(
|
||||
'creator_id' => $earning->creator_id,
|
||||
'adjustment_type' => 'subtract',
|
||||
'amount' => $earning->creator_earning,
|
||||
'previous_balance' => WPDD_Creator::get_creator_balance($earning->creator_id),
|
||||
'new_balance' => WPDD_Creator::get_creator_balance($earning->creator_id) - $earning->creator_earning,
|
||||
'reason' => $reason . ' (Order #' . $earning->order_id . ')',
|
||||
'adjusted_by' => get_current_user_id(),
|
||||
'created_at' => current_time('mysql')
|
||||
),
|
||||
array('%d', '%s', '%f', '%f', '%f', '%s', '%d', '%s')
|
||||
);
|
||||
|
||||
// Update creator balance
|
||||
$current_balance = WPDD_Creator::get_creator_balance($earning->creator_id);
|
||||
update_user_meta($earning->creator_id, 'wpdd_creator_balance', $current_balance - $earning->creator_earning);
|
||||
}
|
||||
|
||||
return $result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get earnings summary for a creator
|
||||
*/
|
||||
public static function get_earnings_summary($creator_id) {
|
||||
global $wpdb;
|
||||
|
||||
$summary = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT
|
||||
COUNT(*) as total_earnings,
|
||||
SUM(CASE WHEN payout_status = 'pending' THEN creator_earning ELSE 0 END) as pending_amount,
|
||||
SUM(CASE WHEN payout_status = 'available' THEN creator_earning ELSE 0 END) as available_amount,
|
||||
SUM(CASE WHEN payout_status = 'paid' THEN creator_earning ELSE 0 END) as paid_amount,
|
||||
SUM(CASE WHEN payout_status = 'cancelled' THEN creator_earning ELSE 0 END) as cancelled_amount,
|
||||
SUM(creator_earning) as total_amount
|
||||
FROM {$wpdb->prefix}wpdd_creator_earnings
|
||||
WHERE creator_id = %d",
|
||||
$creator_id
|
||||
));
|
||||
|
||||
return $summary;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user