I am using the code below to regenerate order's downloadable product permission (including Bundle products), but this code is adding the same PDF multiple times in orders. Can anyone is able to help me to fix this issue?
Also in addition, is there any way I can check if PDF is added in order as a downloadable item then do not add them again within this code?
Can someone please assist with fixing this issue and ensuring that PDFs are not duplicated in the order?
function wc_customer_has_download_permissions($order_id, $product_id)
{
global $wpdb;
// Check if the download permission already exists for the product and order.
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
WHERE order_id = %d AND product_id = %d",
$order_id,
$product_id
));
return $exists > 0;
}
function updates_past_order_pdf_permission()
{
// Exclude cancelled, failed, and refunded statuses
$excluded_statuses = ['wc-cancelled', 'wc-failed', 'wc-refunded'];
$all_statuses = array_keys(wc_get_order_statuses());
$statuses_to_include = array_diff($all_statuses, $excluded_statuses);
// Query orders in the specified date range
$args = [
'limit' => -1,
'status' => $statuses_to_include,
'meta_query' => [
[
'key' => '_created_via',
'value' => 'direct',
'compare' => 'LIKE',
],
],
'date_query' => [
[
'after' => '2025-03-17',
'before' => '2025-03-31',
'inclusive' => true,
],
]
];
$orders = wc_get_orders($args);
if (empty($orders)) {
return 'No orders found.';
}
foreach ($orders as $order) {
// Use an array to track processed products for this order
$processed_products = [];
foreach ($order->get_items() as $item_id => $item) {
$product_id = $item->get_product_id();
$product = wc_get_product($product_id);
// Only process downloadable products
if ($product && $product->is_downloadable()) {
// Prevent duplicate permissions by checking processed array
if (!in_array($product_id, $processed_products) && !wc_customer_has_download_permissions($order->get_id(), $product_id)) {
wc_downloadable_product_permissions($order->get_id(), true, $product_id);
$processed_products[] = $product_id; // Mark this product as processed
}
}
// Handle bundled products
if ($product && $product->is_type('bundle')) {
$bundle_items = $product->get_bundled_items();
foreach ($bundle_items as $bundle_item) {
$child_product_id = $bundle_item->get_product_id();
$child_product = wc_get_product($child_product_id);
// Process child product if it's downloadable and not processed yet
if ($child_product && $child_product->is_downloadable()) {
if (!in_array($child_product_id, $processed_products) && !wc_customer_has_download_permissions($order->get_id(), $child_product_id)) {
wc_downloadable_product_permissions($order->get_id(), true, $child_product_id);
$processed_products[] = $child_product_id; // Mark this child product as processed
}
}
}
}
}
}
return 'Processed successfully.';
}
add_shortcode('updates_past_order_pdf_permission', 'updates_past_order_pdf_permission');
I am using the code below to regenerate order's downloadable product permission (including Bundle products), but this code is adding the same PDF multiple times in orders. Can anyone is able to help me to fix this issue?
Also in addition, is there any way I can check if PDF is added in order as a downloadable item then do not add them again within this code?
Can someone please assist with fixing this issue and ensuring that PDFs are not duplicated in the order?
function wc_customer_has_download_permissions($order_id, $product_id)
{
global $wpdb;
// Check if the download permission already exists for the product and order.
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
WHERE order_id = %d AND product_id = %d",
$order_id,
$product_id
));
return $exists > 0;
}
function updates_past_order_pdf_permission()
{
// Exclude cancelled, failed, and refunded statuses
$excluded_statuses = ['wc-cancelled', 'wc-failed', 'wc-refunded'];
$all_statuses = array_keys(wc_get_order_statuses());
$statuses_to_include = array_diff($all_statuses, $excluded_statuses);
// Query orders in the specified date range
$args = [
'limit' => -1,
'status' => $statuses_to_include,
'meta_query' => [
[
'key' => '_created_via',
'value' => 'direct',
'compare' => 'LIKE',
],
],
'date_query' => [
[
'after' => '2025-03-17',
'before' => '2025-03-31',
'inclusive' => true,
],
]
];
$orders = wc_get_orders($args);
if (empty($orders)) {
return 'No orders found.';
}
foreach ($orders as $order) {
// Use an array to track processed products for this order
$processed_products = [];
foreach ($order->get_items() as $item_id => $item) {
$product_id = $item->get_product_id();
$product = wc_get_product($product_id);
// Only process downloadable products
if ($product && $product->is_downloadable()) {
// Prevent duplicate permissions by checking processed array
if (!in_array($product_id, $processed_products) && !wc_customer_has_download_permissions($order->get_id(), $product_id)) {
wc_downloadable_product_permissions($order->get_id(), true, $product_id);
$processed_products[] = $product_id; // Mark this product as processed
}
}
// Handle bundled products
if ($product && $product->is_type('bundle')) {
$bundle_items = $product->get_bundled_items();
foreach ($bundle_items as $bundle_item) {
$child_product_id = $bundle_item->get_product_id();
$child_product = wc_get_product($child_product_id);
// Process child product if it's downloadable and not processed yet
if ($child_product && $child_product->is_downloadable()) {
if (!in_array($child_product_id, $processed_products) && !wc_customer_has_download_permissions($order->get_id(), $child_product_id)) {
wc_downloadable_product_permissions($order->get_id(), true, $child_product_id);
$processed_products[] = $child_product_id; // Mark this child product as processed
}
}
}
}
}
}
return 'Processed successfully.';
}
add_shortcode('updates_past_order_pdf_permission', 'updates_past_order_pdf_permission');
Share
Improve this question
edited Mar 18 at 9:04
LoicTheAztec
255k24 gold badges399 silver badges446 bronze badges
asked Mar 18 at 6:37
Avinash PatelAvinash Patel
33 bronze badges
3
|
1 Answer
Reset to default 0I have finally got an answer for this question, here below I am sharing full code if anyone want to use it, just make sure you run this code in batch like 01/01/2024 to 01/04/2025 then again for 01/04/2025 to 01/08/2025 to avoid heavy load on the server.
function wc_customer_has_download_permissions($order_id, $product_id)
{
global $wpdb;
// Check if the download permission already exists for the product and order.
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
WHERE order_id = %d AND product_id = %d",
$order_id,
$product_id
));
return $exists > 0;
}
function add_missing_download_permissions($order_id, $product_id)
{
global $wpdb;
$product = wc_get_product($product_id);
if (!$product || !$product->is_downloadable()) {
return;
}
$downloads = $product->get_downloads();
if (empty($downloads)) {
return;
}
$order = wc_get_order($order_id);
$user_id = $order->get_user_id();
$order_key = $order->get_order_key();
$user_email = $order->get_billing_email(); // Ensure email is stored
foreach ($downloads as $download_id => $download) {
$file_exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
WHERE order_id = %d AND product_id = %d AND download_id = %s",
$order_id,
$product_id,
$download_id
));
if ($file_exists == 0) {
$wpdb->insert(
"{$wpdb->prefix}woocommerce_downloadable_product_permissions",
[
'download_id' => $download_id,
'product_id' => $product_id,
'user_id' => $user_id,
'order_id' => $order_id,
'order_key' => $order_key,
'user_email' => $user_email, // Ensure this field is included
'downloads_remaining' => '',
'access_granted' => current_time('mysql'),
'download_count' => 0
],
['%s', '%d', '%d', '%d', '%s', '%s', '%s', '%d']
);
}
}
}
function updates_past_order_pdf_permission()
{
// Exclude cancelled, failed, and refunded statuses
$excluded_statuses = ['wc-cancelled', 'wc-failed', 'wc-refunded'];
$all_statuses = array_keys(wc_get_order_statuses());
$statuses_to_include = array_diff($all_statuses, $excluded_statuses);
// Query orders in the specified date range
$args = [
'limit' => -1,
'status' => $statuses_to_include,
'meta_query' => [
[
'key' => '_created_via',
'value' => 'direct',
'compare' => 'LIKE',
],
],
'date_query' => [
[
'after' => '2025-05-01',
'before' => '2025-12-31',
'inclusive' => true,
],
]
];
$orders = wc_get_orders($args);
if (empty($orders)) {
return 'No orders found.';
}
foreach ($orders as $order) {
$order_id = $order->get_id();
foreach ($order->get_items() as $item_id => $item) {
$product_id = $item->get_product_id();
$product = wc_get_product($product_id);
// Process main product
if ($product && $product->is_downloadable()) {
add_missing_download_permissions($order_id, $product_id);
}
// Process bundled products
if ($product && $product->is_type('bundle')) {
$bundle_items = $product->get_bundled_items();
foreach ($bundle_items as $bundle_item) {
$child_product_id = $bundle_item->get_product_id();
$child_product = wc_get_product($child_product_id);
if ($child_product && $child_product->is_downloadable()) {
add_missing_download_permissions($order_id, $child_product_id);
}
}
}
}
}
return 'Processed successfully.';
}
add_shortcode('updates_past_order_pdf_permission', 'updates_past_order_pdf_permission');
wc_customer_has_download_permissions
is giving correct results in each possible case? – C3roe Commented Mar 18 at 9:26wc_downloadable_product_permissions
has only 2 arguments (not 3):$order_id
(integer) Order ID, and$force
(boolean) Force downloadable permissions. Sowc_downloadable_product_permissions
can't target any specific product ID and needs to be used one time for each order. Note that the rule in stack overflow is one question at the time, not 2. – LoicTheAztec Commented Mar 18 at 9:42