修复WooCommerce订单重复添加PDF下载权限问题求助
修复WooCommerce批量再生可下载权限时重复添加PDF的问题
问题说明
使用给定的PHP代码批量为WooCommerce订单(包含Bundle产品)再生可下载产品权限时,会出现同一PDF被重复添加到订单的情况。需要修复代码,实现若PDF已作为可下载项存在于订单中,则不再重复添加的逻辑。
原代码问题分析
原代码的wc_customer_has_download_permissions函数仅通过order_id和product_id判断权限是否存在,但WooCommerce的woocommerce_downloadable_product_permissions表中,同一产品可能对应多个下载文件,该函数无法精准判断具体的PDF文件是否已存在于订单的下载权限中,这是导致重复添加的核心原因。此外,processed_products数组仅记录已处理的产品ID,无法覆盖同一产品下多个下载项的重复检查场景。
修复后的代码
function wc_order_has_download_file($order_id, $product_id, $download_id) { global $wpdb; // 精准检查指定订单、产品、下载文件的权限是否已存在 $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 )); return $exists > 0; } function updates_past_order_pdf_permission() { // 排除已取消、失败、退款的订单状态 $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); // 查询指定日期范围内的订单 $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 '未找到符合条件的订单。'; } foreach ($orders as $order) { $order_id = $order->get_id(); // 记录已处理的[产品ID-下载文件ID]组合,避免重复添加 $processed_downloads = []; foreach ($order->get_items() as $item) { $product_id = $item->get_product_id(); $product = wc_get_product($product_id); // 处理普通可下载产品 if ($product && $product->is_downloadable()) { $downloads = $product->get_downloads(); foreach ($downloads as $download_id => $download) { $key = "{$product_id}-{$download_id}"; if (!in_array($key, $processed_downloads) && !wc_order_has_download_file($order_id, $product_id, $download_id)) { // 为指定产品的指定下载文件添加权限 wc_downloadable_product_permissions($order_id, true, $product_id, $item->get_quantity(), $download_id); $processed_downloads[] = $key; } } } // 处理Bundle产品中的子产品 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()) { $child_downloads = $child_product->get_downloads(); foreach ($child_downloads as $download_id => $download) { $key = "{$child_product_id}-{$download_id}"; if (!in_array($key, $processed_downloads) && !wc_order_has_download_file($order_id, $child_product_id, $download_id)) { wc_downloadable_product_permissions($order_id, true, $child_product_id, $bundle_item->get_quantity(), $download_id); $processed_downloads[] = $key; } } } } } } } return '处理完成。'; } add_shortcode('updates_past_order_pdf_permission', 'updates_past_order_pdf_permission');
修复说明
- 新增精准检查函数:
wc_order_has_download_file通过order_id、product_id和download_id三重条件查询,确保只有当指定的PDF文件未存在于订单权限中时,才会执行添加操作。 - 跟踪已处理的下载项:使用
$processed_downloads数组记录已处理的[产品ID-下载文件ID]组合,避免同一订单内重复处理同一PDF。 - 调用
wc_downloadable_product_permissions时指定download_id:原代码未指定具体下载文件ID,导致函数可能为产品的所有下载项重复添加权限;修复后指定download_id,仅处理目标PDF文件。 - 保留原有订单筛选逻辑:继续排除无效订单状态、筛选指定创建方式和日期范围的订单,确保处理范围准确。
内容的提问来源于stack exchange,提问作者Avinash Patel
相关产品推荐
相关产品推荐

