Last active
August 7, 2025 01:43
-
-
Save shameemreza/2dc2b560bed4d9e18d9bc7ecece9db87 to your computer and use it in GitHub Desktop.
Prevents WooCommerce Subscription Downloads from adding downloadable products as separate line items in subscription orders, while keeping download access intact.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Hide zero-priced downloadable products from subscription line items. | |
| */ | |
| function wcsd_hide_zero_priced_downloads() { | |
| // Filter the line items display only, not affecting the actual data. | |
| add_filter( 'woocommerce_order_get_items', 'wcsd_filter_subscription_items', 10, 3 ); | |
| // IMPORTANT: We're NOT removing the original download_permissions action | |
| // so download permissions are still properly granted. | |
| } | |
| add_action( 'init', 'wcsd_hide_zero_priced_downloads', 20 ); | |
| /** | |
| * Filter subscription line items to hide zero-priced downloadable products. | |
| * | |
| * @param array $items Array of WC_Order_Item objects. | |
| * @param WC_Order $order Order or subscription object. | |
| * @return array Filtered items. | |
| */ | |
| function wcsd_filter_subscription_items( $items, $order ) { | |
| // Only process for subscriptions on the frontend. | |
| if ( ! is_a( $order, 'WC_Subscription' ) || is_admin() ) { | |
| return $items; | |
| } | |
| // Create a new array to hold the filtered items. | |
| $filtered_items = array(); | |
| foreach ( $items as $item_id => $item ) { | |
| // Skip if not a line item. | |
| if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) { | |
| $filtered_items[$item_id] = $item; | |
| continue; | |
| } | |
| // Get item total. | |
| $item_total = $item->get_total(); | |
| // If the item has a price greater than zero, keep it. | |
| if ( $item_total > 0 ) { | |
| $filtered_items[$item_id] = $item; | |
| } | |
| } | |
| return $filtered_items; | |
| } | |
| /** | |
| * Make downloads accessible from the My Account > Downloads section. | |
| * This is crucial because we're hiding some line items but need their downloads to be accessible. | |
| */ | |
| function wcsd_ensure_downloads_available() { | |
| add_filter( 'woocommerce_customer_get_downloadable_products', 'wcsd_include_all_downloads', 10, 1 ); | |
| } | |
| add_action( 'init', 'wcsd_ensure_downloads_available', 30 ); | |
| /** | |
| * Include all downloadable products in the customer's downloads section. | |
| * | |
| * @param array $downloads Array of downloadable products. | |
| * @return array Updated downloads array. | |
| */ | |
| function wcsd_include_all_downloads( $downloads ) { | |
| // Don't modify if not logged in | |
| if ( ! is_user_logged_in() ) { | |
| return $downloads; | |
| } | |
| $user_id = get_current_user_id(); | |
| // Get all active subscriptions for the user | |
| $subscriptions = wcs_get_users_subscriptions( $user_id ); | |
| foreach ( $subscriptions as $subscription ) { | |
| // Only for active subscriptions | |
| if ( ! $subscription->has_status( 'active' ) ) { | |
| continue; | |
| } | |
| // Get all downloadable products associated with subscription items | |
| foreach ( $subscription->get_items() as $item ) { | |
| $product_id = $item->get_product_id(); | |
| $variation_id = $item->get_variation_id(); | |
| // Get linked downloadable products | |
| if ( class_exists( 'WC_Subscription_Downloads' ) ) { | |
| $downloadable_products = WC_Subscription_Downloads::get_downloadable_products( $product_id, $variation_id ); | |
| foreach ( $downloadable_products as $download_product_id ) { | |
| $product = wc_get_product( $download_product_id ); | |
| if ( ! $product || ! $product->is_downloadable() ) { | |
| continue; | |
| } | |
| // Get the downloadable files | |
| $files = $product->get_downloads(); | |
| if ( empty( $files ) ) { | |
| continue; | |
| } | |
| // Add each file to the downloads array | |
| foreach ( $files as $download_id => $file ) { | |
| // Create a unique download ID to avoid duplicates | |
| $unique_id = md5( $subscription->get_id() . '_' . $download_product_id . '_' . $download_id ); | |
| // Add to downloads array with all required fields | |
| $downloads[$unique_id] = array( | |
| 'download_url' => $file['file'], | |
| 'download_id' => $download_id, | |
| 'product_id' => $download_product_id, | |
| 'product_name' => $product->get_name(), | |
| 'downloads_remaining' => '', | |
| 'access_expires' => '', | |
| 'file' => array( | |
| 'name' => $file['name'], | |
| 'file' => $file['file'] | |
| ), | |
| 'order_id' => $subscription->get_id(), | |
| 'order_key' => $subscription->get_order_key(), | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return $downloads; | |
| } |
Author
shameemreza
commented
Aug 6, 2025

Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment