admin管理员组文章数量:1387309
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');
本文标签: Bulk regenerate download permission for woocommerce ordersStack Overflow
版权声明:本文标题:Bulk regenerate download permission for woocommerce orders: - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744522120a2610516.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
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