First Commit
This commit is contained in:
752
includes/class-wpdd-download-handler.php
Normal file
752
includes/class-wpdd-download-handler.php
Normal file
@@ -0,0 +1,752 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WPDD_Download_Handler {
|
||||
|
||||
public static function init() {
|
||||
// Use priority 1 to ensure our handler runs early
|
||||
add_action('init', array(__CLASS__, 'handle_download_request'), 1);
|
||||
add_action('init', array(__CLASS__, 'handle_secure_file_download'), 1);
|
||||
add_action('init', array(__CLASS__, 'handle_protected_download'), 1);
|
||||
|
||||
// Also hook to template_redirect as a fallback
|
||||
add_action('template_redirect', array(__CLASS__, 'handle_download_request'), 1);
|
||||
|
||||
// Debug: Add a test endpoint for admins
|
||||
if (current_user_can('manage_options') && isset($_GET['wpdd_test_download'])) {
|
||||
add_action('init', function() {
|
||||
wp_die('WPDD Download Handler is loaded and working! Current time: ' . current_time('mysql'));
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static function handle_download_request() {
|
||||
// TESTING: Add a test parameter to verify changes are taking effect
|
||||
if (isset($_GET['test_update_working'])) {
|
||||
wp_die('TEST: Changes are working! File updated successfully.');
|
||||
}
|
||||
|
||||
// Early exit if not a download request
|
||||
if (!isset($_GET['wpdd_download']) && !isset($_GET['wpdd_download_token'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug logging for admin users
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Download request detected!');
|
||||
error_log('WPDD Debug: GET params: ' . print_r($_GET, true));
|
||||
error_log('WPDD Debug: Current action: ' . current_action());
|
||||
}
|
||||
|
||||
if (isset($_GET['wpdd_download'])) {
|
||||
// Add debug output before processing
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Processing download by order ID: ' . $_GET['wpdd_download']);
|
||||
}
|
||||
self::process_download_by_order();
|
||||
exit; // Make sure we exit after processing
|
||||
}
|
||||
|
||||
if (isset($_GET['wpdd_download_token'])) {
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Processing download by token: ' . $_GET['wpdd_download_token']);
|
||||
}
|
||||
self::process_download_by_token();
|
||||
exit; // Make sure we exit after processing
|
||||
}
|
||||
}
|
||||
|
||||
public static function handle_protected_download() {
|
||||
if (!isset($_GET['wpdd_protected_download'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file_id = sanitize_text_field($_GET['wpdd_protected_download']);
|
||||
$token = sanitize_text_field($_GET['token'] ?? '');
|
||||
|
||||
if (!$file_id || !$token) {
|
||||
wp_die(__('Invalid download link.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Get file metadata
|
||||
$file_meta = get_option('wpdd_protected_file_' . $file_id);
|
||||
|
||||
if (!$file_meta || $file_meta['token'] !== $token) {
|
||||
wp_die(__('Invalid download token.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
if (!file_exists($file_meta['file_path'])) {
|
||||
wp_die(__('File not found.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Deliver the file
|
||||
self::deliver_protected_file($file_meta['file_path']);
|
||||
}
|
||||
|
||||
private static function process_download_by_order() {
|
||||
$download_link_id = intval($_GET['wpdd_download']);
|
||||
|
||||
// Debug nonce verification
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Download Link ID: ' . $download_link_id);
|
||||
error_log('WPDD Debug: Nonce received: ' . ($_GET['_wpnonce'] ?? 'none'));
|
||||
error_log('WPDD Debug: Expected nonce action: wpdd_download_' . $download_link_id);
|
||||
}
|
||||
|
||||
if (!wp_verify_nonce($_GET['_wpnonce'] ?? '', 'wpdd_download_' . $download_link_id)) {
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Nonce verification failed!');
|
||||
}
|
||||
wp_die(__('Invalid download link.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// First get the download link to find the associated order
|
||||
$download_link = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}wpdd_download_links WHERE id = %d",
|
||||
$download_link_id
|
||||
));
|
||||
|
||||
if (!$download_link) {
|
||||
wp_die(__('Invalid download link.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
$order_id = $download_link->order_id;
|
||||
|
||||
// Check by email if guest
|
||||
if (isset($_GET['customer_email']) && isset($_GET['key'])) {
|
||||
$email = sanitize_email($_GET['customer_email']);
|
||||
$key = sanitize_text_field($_GET['key']);
|
||||
|
||||
// Verify the key
|
||||
$expected_key = substr(md5($email . AUTH_KEY), 0, 10);
|
||||
if ($key !== $expected_key) {
|
||||
wp_die(__('Invalid access key.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
$order = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}wpdd_orders
|
||||
WHERE id = %d AND customer_email = %s AND status = 'completed'",
|
||||
$order_id,
|
||||
$email
|
||||
));
|
||||
} elseif (is_user_logged_in()) {
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
$order = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}wpdd_orders
|
||||
WHERE id = %d AND (customer_id = %d OR customer_email = %s) AND status = 'completed'",
|
||||
$order_id,
|
||||
$current_user->ID,
|
||||
$current_user->user_email
|
||||
));
|
||||
} else {
|
||||
// For unregistered users, try to look up order by order number from URL if available
|
||||
if (isset($_GET['order_id'])) {
|
||||
$order_number = sanitize_text_field($_GET['order_id']);
|
||||
|
||||
// Look up order by order ID and verify it matches the order number
|
||||
$order = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}wpdd_orders
|
||||
WHERE id = %d AND order_number = %s AND status = 'completed'",
|
||||
$order_id,
|
||||
$order_number
|
||||
));
|
||||
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Guest order lookup - Order ID: ' . $order_id . ', Order Number: ' . $order_number . ', Found: ' . ($order ? 'Yes' : 'No'));
|
||||
}
|
||||
|
||||
if (!$order) {
|
||||
wp_die(__('Invalid order or order not found.', 'wp-digital-download'));
|
||||
}
|
||||
} else {
|
||||
// Debug: Show what parameters we have
|
||||
$debug_info = '';
|
||||
if (current_user_can('manage_options')) {
|
||||
$debug_info = '<br><br>Debug info:<br>';
|
||||
$debug_info .= 'GET params: ' . print_r($_GET, true);
|
||||
$debug_info .= '<br>User logged in: ' . (is_user_logged_in() ? 'Yes' : 'No');
|
||||
}
|
||||
wp_die(__('You must be logged in to download this product or provide a valid order reference.', 'wp-digital-download') . $debug_info);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$order) {
|
||||
wp_die(__('Invalid order or you do not have permission to download this product.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
self::process_download($order);
|
||||
}
|
||||
|
||||
private static function process_download_by_token() {
|
||||
$token = sanitize_text_field($_GET['wpdd_download_token']);
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$download_link = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT dl.*, o.*
|
||||
FROM {$wpdb->prefix}wpdd_download_links dl
|
||||
INNER JOIN {$wpdb->prefix}wpdd_orders o ON dl.order_id = o.id
|
||||
WHERE dl.token = %s",
|
||||
$token
|
||||
));
|
||||
|
||||
if (!$download_link) {
|
||||
wp_die(__('Invalid download link.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
if ($download_link->expires_at < current_time('mysql')) {
|
||||
// Check if user still has downloads remaining
|
||||
if ($download_link->max_downloads > 0 && $download_link->download_count >= $download_link->max_downloads) {
|
||||
wp_die(__('This download link has expired and you have no downloads remaining.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Only send refresh email if this appears to be a real user attempt (not automated)
|
||||
// Check if the customer is unregistered (has no user account)
|
||||
$is_unregistered_customer = ($download_link->customer_id == 0);
|
||||
|
||||
if ($is_unregistered_customer) {
|
||||
// Generate new token and send refresh email only for unregistered customers
|
||||
$new_token = self::refresh_download_token($download_link->order_id, $download_link->customer_email);
|
||||
|
||||
if ($new_token) {
|
||||
wp_die(sprintf(
|
||||
__('Your download link has expired. A new download link has been sent to %s. Please check your email and try again.', 'wp-digital-download'),
|
||||
esc_html($download_link->customer_email)
|
||||
));
|
||||
} else {
|
||||
wp_die(__('This download link has expired and could not be refreshed. Please contact support.', 'wp-digital-download'));
|
||||
}
|
||||
} else {
|
||||
// For registered users, just show expired message (they can log in to get new links)
|
||||
wp_die(__('This download link has expired. Please log in to your account to get a new download link.', 'wp-digital-download'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($download_link->max_downloads > 0 && $download_link->download_count >= $download_link->max_downloads) {
|
||||
wp_die(__('Download limit exceeded.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
$wpdb->update(
|
||||
$wpdb->prefix . 'wpdd_download_links',
|
||||
array('download_count' => $download_link->download_count + 1),
|
||||
array('id' => $download_link->id),
|
||||
array('%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
self::process_download($download_link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an expired download token and send new link via email
|
||||
*/
|
||||
private static function refresh_download_token($order_id, $customer_email) {
|
||||
global $wpdb;
|
||||
|
||||
// Generate new token with extended expiry (72 hours as suggested)
|
||||
$new_token = wp_hash(uniqid() . $order_id . time());
|
||||
$new_expires_at = date('Y-m-d H:i:s', strtotime('+72 hours'));
|
||||
|
||||
// Update the existing download link with new token and expiry
|
||||
$updated = $wpdb->update(
|
||||
$wpdb->prefix . 'wpdd_download_links',
|
||||
array(
|
||||
'token' => $new_token,
|
||||
'expires_at' => $new_expires_at,
|
||||
'refreshed_at' => current_time('mysql')
|
||||
),
|
||||
array('order_id' => $order_id),
|
||||
array('%s', '%s', '%s'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if (!$updated) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send refresh email
|
||||
self::send_refresh_email($order_id, $new_token, $customer_email);
|
||||
|
||||
return $new_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send refresh email with new download link
|
||||
*/
|
||||
private static function send_refresh_email($order_id, $token, $customer_email) {
|
||||
global $wpdb;
|
||||
|
||||
// Get order details
|
||||
$order = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT o.*, p.post_title as product_name
|
||||
FROM {$wpdb->prefix}wpdd_orders o
|
||||
LEFT JOIN {$wpdb->posts} p ON o.product_id = p.ID
|
||||
WHERE o.id = %d",
|
||||
$order_id
|
||||
));
|
||||
|
||||
if (!$order) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$download_url = add_query_arg(array(
|
||||
'wpdd_download_token' => $token
|
||||
), home_url());
|
||||
|
||||
$subject = sprintf(__('New Download Link for %s', 'wp-digital-download'), $order->product_name);
|
||||
|
||||
$message = sprintf(
|
||||
__("Hello %s,\n\nYour download link for \"%s\" has expired, so we've generated a new one for you.\n\nThis new link is valid for 72 hours and can be used for your remaining downloads.\n\nDownload Link: %s\n\nOrder Number: %s\nPurchase Date: %s\n\nIf you have any issues, please contact our support team.\n\nBest regards,\n%s", 'wp-digital-download'),
|
||||
$order->customer_name,
|
||||
$order->product_name,
|
||||
$download_url,
|
||||
$order->order_number,
|
||||
date_i18n(get_option('date_format'), strtotime($order->purchase_date)),
|
||||
get_bloginfo('name')
|
||||
);
|
||||
|
||||
$headers = array('Content-Type: text/plain; charset=UTF-8');
|
||||
|
||||
return wp_mail($customer_email, $subject, $message, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create download token for orders that don't have one (legacy orders)
|
||||
*/
|
||||
public static function ensure_download_token($order_id) {
|
||||
global $wpdb;
|
||||
|
||||
// Check if token already exists
|
||||
$existing_token = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT token FROM {$wpdb->prefix}wpdd_download_links WHERE order_id = %d",
|
||||
$order_id
|
||||
));
|
||||
|
||||
if ($existing_token) {
|
||||
return $existing_token;
|
||||
}
|
||||
|
||||
// Create new token for legacy order
|
||||
$token = wp_hash(uniqid() . $order_id . time());
|
||||
$expires_at = date('Y-m-d H:i:s', strtotime('+7 days'));
|
||||
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'wpdd_download_links',
|
||||
array(
|
||||
'order_id' => $order_id,
|
||||
'token' => $token,
|
||||
'expires_at' => $expires_at,
|
||||
'max_downloads' => 5,
|
||||
'created_at' => current_time('mysql')
|
||||
),
|
||||
array('%d', '%s', '%s', '%d', '%s')
|
||||
);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
private static function process_download($order) {
|
||||
$product_id = $order->product_id;
|
||||
$files = get_post_meta($product_id, '_wpdd_files', true);
|
||||
|
||||
// Debug output for admins
|
||||
if (current_user_can('manage_options') && empty($files)) {
|
||||
wp_die(sprintf(__('Debug: No files found for product ID %d. Files data: %s', 'wp-digital-download'),
|
||||
$product_id, '<pre>' . print_r($files, true) . '</pre>'));
|
||||
}
|
||||
|
||||
if (empty($files)) {
|
||||
wp_die(__('No files available for download.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Debug output for admins
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Files for product ' . $product_id . ': ' . print_r($files, true));
|
||||
}
|
||||
|
||||
$download_limit = get_post_meta($product_id, '_wpdd_download_limit', true);
|
||||
$download_expiry = get_post_meta($product_id, '_wpdd_download_expiry', true);
|
||||
|
||||
if ($download_expiry > 0) {
|
||||
$expiry_date = date('Y-m-d H:i:s', strtotime($order->purchase_date . ' + ' . $download_expiry . ' days'));
|
||||
if (current_time('mysql') > $expiry_date) {
|
||||
wp_die(__('Your download period has expired.', 'wp-digital-download'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($download_limit > 0 && $order->download_count >= $download_limit) {
|
||||
wp_die(__('You have reached the download limit for this product.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$wpdb->update(
|
||||
$wpdb->prefix . 'wpdd_orders',
|
||||
array('download_count' => $order->download_count + 1),
|
||||
array('id' => $order->id),
|
||||
array('%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
$file_index = isset($_GET['file']) ? intval($_GET['file']) : 0;
|
||||
|
||||
// Handle array structure - files might be indexed or not
|
||||
$file_list = array_values($files); // Reindex to ensure numeric keys
|
||||
|
||||
if (count($file_list) > 1 && !isset($_GET['file'])) {
|
||||
self::show_file_selection($file_list, $order);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($file_list[$file_index])) {
|
||||
// Debug output for admins
|
||||
if (current_user_can('manage_options')) {
|
||||
wp_die(sprintf(__('Debug: File index %d not found. Available files: %s', 'wp-digital-download'),
|
||||
$file_index, '<pre>' . print_r($file_list, true) . '</pre>'));
|
||||
}
|
||||
wp_die(__('File not found.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
$file = $file_list[$file_index];
|
||||
|
||||
self::log_download($order, $product_id, $file['id'] ?? $file_index);
|
||||
|
||||
// Debug for admins
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Processing file - ID: ' . ($file['id'] ?? 'none') . ', URL: ' . ($file['url'] ?? 'none'));
|
||||
}
|
||||
|
||||
// Check if this is a protected file
|
||||
if (isset($file['id']) && strpos($file['id'], 'wpdd_') === 0) {
|
||||
// This is a protected file, get its metadata
|
||||
$file_meta = get_option('wpdd_protected_file_' . $file['id']);
|
||||
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Protected file detected - ' . $file['id']);
|
||||
error_log('WPDD Debug: File meta exists: ' . ($file_meta ? 'Yes' : 'No'));
|
||||
if ($file_meta) {
|
||||
error_log('WPDD Debug: File path exists: ' . (file_exists($file_meta['file_path']) ? 'Yes' : 'No'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($file_meta && file_exists($file_meta['file_path'])) {
|
||||
$enable_watermark = get_post_meta($product_id, '_wpdd_enable_watermark', true);
|
||||
|
||||
if ($enable_watermark && self::is_watermarkable($file_meta['file_path'])) {
|
||||
$watermarked_file = WPDD_Watermark::apply_watermark($file_meta['file_path'], $order);
|
||||
if ($watermarked_file) {
|
||||
self::deliver_protected_file($watermarked_file, true);
|
||||
} else {
|
||||
self::deliver_protected_file($file_meta['file_path']);
|
||||
}
|
||||
} else {
|
||||
self::deliver_protected_file($file_meta['file_path']);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if URL contains protected download parameter (alternative check)
|
||||
if (isset($file['url']) && strpos($file['url'], 'wpdd_protected_download=') !== false) {
|
||||
// Extract file_id from URL
|
||||
if (preg_match('/wpdd_protected_download=([^&]+)/', $file['url'], $matches)) {
|
||||
$file_id = $matches[1];
|
||||
$file_meta = get_option('wpdd_protected_file_' . $file_id);
|
||||
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Protected URL detected - ' . $file_id);
|
||||
}
|
||||
|
||||
if ($file_meta && file_exists($file_meta['file_path'])) {
|
||||
$enable_watermark = get_post_meta($product_id, '_wpdd_enable_watermark', true);
|
||||
|
||||
if ($enable_watermark && self::is_watermarkable($file_meta['file_path'])) {
|
||||
$watermarked_file = WPDD_Watermark::apply_watermark($file_meta['file_path'], $order);
|
||||
if ($watermarked_file) {
|
||||
self::deliver_protected_file($watermarked_file, true);
|
||||
} else {
|
||||
self::deliver_protected_file($file_meta['file_path']);
|
||||
}
|
||||
} else {
|
||||
self::deliver_protected_file($file_meta['file_path']);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Regular file handling (backward compatibility)
|
||||
$enable_watermark = get_post_meta($product_id, '_wpdd_enable_watermark', true);
|
||||
|
||||
if ($enable_watermark && self::is_watermarkable($file['url'])) {
|
||||
$watermarked_file = WPDD_Watermark::apply_watermark($file['url'], $order);
|
||||
if ($watermarked_file) {
|
||||
self::deliver_file($watermarked_file, $file['name'], true);
|
||||
} else {
|
||||
self::deliver_file($file['url'], $file['name']);
|
||||
}
|
||||
} else {
|
||||
self::deliver_file($file['url'], $file['name']);
|
||||
}
|
||||
}
|
||||
|
||||
private static function show_file_selection($files, $order) {
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html <?php language_attributes(); ?>>
|
||||
<head>
|
||||
<meta charset="<?php bloginfo('charset'); ?>">
|
||||
<title><?php _e('Select File to Download', 'wp-digital-download'); ?></title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
max-width: 600px;
|
||||
margin: 50px auto;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.file-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
.file-item {
|
||||
margin-bottom: 15px;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.file-name {
|
||||
font-weight: 500;
|
||||
}
|
||||
.download-btn {
|
||||
padding: 8px 16px;
|
||||
background: #2271b1;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.download-btn:hover {
|
||||
background: #135e96;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1><?php _e('Select File to Download', 'wp-digital-download'); ?></h1>
|
||||
<ul class="file-list">
|
||||
<?php foreach ($files as $index => $file) : ?>
|
||||
<li class="file-item">
|
||||
<span class="file-name"><?php echo esc_html($file['name'] ?? 'File ' . ($index + 1)); ?></span>
|
||||
<a href="<?php echo add_query_arg('file', $index); ?>" class="download-btn">
|
||||
<?php _e('Download', 'wp-digital-download'); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function handle_secure_file_download() {
|
||||
if (!isset($_GET['wpdd_file_download'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attachment_id = intval($_GET['wpdd_file_download']);
|
||||
$token = sanitize_text_field($_GET['token'] ?? '');
|
||||
|
||||
if (!$attachment_id || !$token) {
|
||||
wp_die(__('Invalid download link.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Verify token
|
||||
$stored_token = get_post_meta($attachment_id, '_wpdd_download_token', true);
|
||||
if ($token !== $stored_token) {
|
||||
wp_die(__('Invalid download token.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Check if user has permission to download
|
||||
if (!is_user_logged_in()) {
|
||||
wp_die(__('You must be logged in to download this file.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Get protected file path
|
||||
$protected_path = get_post_meta($attachment_id, '_wpdd_protected_path', true);
|
||||
if (!$protected_path || !file_exists($protected_path)) {
|
||||
// Fallback to regular attachment path
|
||||
$protected_path = get_attached_file($attachment_id);
|
||||
}
|
||||
|
||||
if (!$protected_path || !file_exists($protected_path)) {
|
||||
wp_die(__('File not found.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
// Deliver the file
|
||||
self::deliver_protected_file($protected_path);
|
||||
}
|
||||
|
||||
private static function deliver_protected_file($file_path, $is_temp = false) {
|
||||
if (!file_exists($file_path)) {
|
||||
wp_die(__('File not found.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
$file_name = basename($file_path);
|
||||
$file_size = filesize($file_path);
|
||||
$file_type = wp_check_filetype($file_path);
|
||||
|
||||
nocache_headers();
|
||||
|
||||
header('Content-Type: ' . ($file_type['type'] ?: 'application/octet-stream'));
|
||||
header('Content-Disposition: attachment; filename="' . $file_name . '"');
|
||||
header('Content-Length: ' . $file_size);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
if (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
readfile($file_path);
|
||||
|
||||
if ($is_temp && file_exists($file_path)) {
|
||||
unlink($file_path);
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
private static function deliver_file($file_path, $file_name, $is_temp = false) {
|
||||
$original_path = $file_path;
|
||||
|
||||
// Check if this is a protected file URL
|
||||
if (strpos($file_path, 'wpdd_file_download=') !== false) {
|
||||
// This is already a protected URL, just redirect to it
|
||||
wp_redirect($file_path);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check if file is in protected directory
|
||||
$upload_dir = wp_upload_dir();
|
||||
$protected_dir = trailingslashit($upload_dir['basedir']) . WPDD_UPLOADS_DIR;
|
||||
|
||||
if (strpos($file_path, $protected_dir) === 0) {
|
||||
// File is in protected directory, deliver directly
|
||||
if (!file_exists($file_path)) {
|
||||
wp_die(__('Protected file not found.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
self::deliver_protected_file($file_path);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert URL to file path if needed
|
||||
if (filter_var($file_path, FILTER_VALIDATE_URL)) {
|
||||
$upload_dir = wp_upload_dir();
|
||||
$site_url = get_site_url();
|
||||
|
||||
// Debug logging
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Original URL: ' . $file_path);
|
||||
error_log('WPDD Debug: Upload baseurl: ' . $upload_dir['baseurl']);
|
||||
error_log('WPDD Debug: Upload basedir: ' . $upload_dir['basedir']);
|
||||
}
|
||||
|
||||
// Handle various URL formats
|
||||
if (strpos($file_path, $upload_dir['baseurl']) === 0) {
|
||||
$file_path = str_replace($upload_dir['baseurl'], $upload_dir['basedir'], $file_path);
|
||||
} elseif (strpos($file_path, $site_url) === 0) {
|
||||
// Handle site URL paths
|
||||
$file_path = str_replace($site_url . '/wp-content/uploads', $upload_dir['basedir'], $file_path);
|
||||
} else {
|
||||
// External URL - just redirect
|
||||
wp_redirect($file_path);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug logging
|
||||
if (current_user_can('manage_options')) {
|
||||
error_log('WPDD Debug: Final file path: ' . $file_path);
|
||||
error_log('WPDD Debug: File exists: ' . (file_exists($file_path) ? 'Yes' : 'No'));
|
||||
}
|
||||
|
||||
if (!file_exists($file_path)) {
|
||||
// Debug output for admin users
|
||||
if (current_user_can('manage_options')) {
|
||||
wp_die(sprintf(__('File not found at path: %s<br>Original: %s', 'wp-digital-download'),
|
||||
$file_path, $original_path));
|
||||
}
|
||||
wp_die(__('File not found. Please contact the administrator.', 'wp-digital-download'));
|
||||
}
|
||||
|
||||
$file_size = filesize($file_path);
|
||||
$file_type = wp_check_filetype($file_path);
|
||||
|
||||
if (empty($file_name)) {
|
||||
$file_name = basename($file_path);
|
||||
}
|
||||
|
||||
nocache_headers();
|
||||
|
||||
header('Content-Type: ' . ($file_type['type'] ?: 'application/octet-stream'));
|
||||
header('Content-Disposition: attachment; filename="' . $file_name . '"');
|
||||
header('Content-Length: ' . $file_size);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
if (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
readfile($file_path);
|
||||
|
||||
if ($is_temp && file_exists($file_path)) {
|
||||
unlink($file_path);
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
private static function log_download($order, $product_id, $file_id) {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'wpdd_downloads',
|
||||
array(
|
||||
'order_id' => $order->id,
|
||||
'product_id' => $product_id,
|
||||
'customer_id' => $order->customer_id,
|
||||
'file_id' => $file_id,
|
||||
'download_date' => current_time('mysql'),
|
||||
'ip_address' => $_SERVER['REMOTE_ADDR'],
|
||||
'user_agent' => $_SERVER['HTTP_USER_AGENT']
|
||||
),
|
||||
array('%d', '%d', '%d', '%s', '%s', '%s', '%s')
|
||||
);
|
||||
}
|
||||
|
||||
private static function is_watermarkable($file_url) {
|
||||
$supported_types = array('jpg', 'jpeg', 'png', 'gif', 'pdf');
|
||||
$file_extension = strtolower(pathinfo($file_url, PATHINFO_EXTENSION));
|
||||
return in_array($file_extension, $supported_types);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user