phpwordpresswoocommercehook-woocommerce

Change download_url in WooCommerce


I want to change the download_url on My account downloads section in WooCommerce


Therefore I changed home_url( '/' ) to home_url( '/account/downloads/' ) using the hook below:

function filter_woocommerce_customer_available_downloads( $downloads, $customer_id ) { 
    $downloads   = array();
    $_product    = null;
    $order       = null;
    $file_number = 0;

    // Get results from valid orders only.
    $results = wc_get_customer_download_permissions( $customer_id );

    if ( $results ) {
        foreach ( $results as $result ) {
            $order_id = intval( $result->order_id );

            if ( ! $order || $order->get_id() !== $order_id ) {
                // New order.
                $order    = wc_get_order( $order_id );
                $_product = null;
            }

            // Make sure the order exists for this download.
            if ( ! $order ) {
                continue;
            }

            // Check if downloads are permitted.
            if ( ! $order->is_download_permitted() ) {
                continue;
            }

            $product_id = intval( $result->product_id );

            if ( ! $_product || $_product->get_id() !== $product_id ) {
                // New product.
                $file_number = 0;
                $_product    = wc_get_product( $product_id );
            }

            // Check product exists and has the file.
            if ( ! $_product || ! $_product->exists() || ! $_product->has_file( $result->download_id ) ) {
                continue;
            }

            $download_file = $_product->get_file( $result->download_id );

            // If the downloadable file has been disabled (it may be located in an untrusted location) then do not return it.
            if ( ! $download_file->get_enabled() ) {
                continue;
            }

            // Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files.
            $download_name = apply_filters(
                'woocommerce_downloadable_product_name',
                $download_file['name'],
                $_product,
                $result->download_id,
                $file_number
            );

            $downloads[] = array(
                'download_url'        => add_query_arg(
                    array(
                        'download_file' => $product_id,
                        'order'         => $result->order_key,
                        'email'         => rawurlencode( $result->user_email ),
                        'key'           => $result->download_id,
                    ),
                    home_url( '/account/downloads/' )
                ),
                'download_id'         => $result->download_id,
                'product_id'          => $_product->get_id(),
                'product_name'        => $_product->get_name(),
                'product_url'         => $_product->is_visible() ? $_product->get_permalink() : '', // Since 3.3.0.
                'download_name'       => $download_name,
                'order_id'            => $order->get_id(),
                'order_key'           => $order->get_order_key(),
                'downloads_remaining' => $result->downloads_remaining,
                'access_expires'      => $result->access_expires,
                'file'                => array(
                    'name' => $download_file->get_name(),
                    'file' => $download_file->get_file(),
                ),
            );

            $file_number++;
        }
    }
    return $downloads; 
} add_filter( 'woocommerce_customer_available_downloads', 'filter_woocommerce_customer_available_downloads', 10, 2 );

Code is based on the wc_get_customer_available_downloads( $customer_id ) function, which can be found in /includes/wc-user-functions.php file

Is it possible to summarize the hook?


Solution

  • The woocommerce_customer_available_downloads filter hook does indeed allow you to change download_url, however it is not necessary to rewrite the entire function via the hook, as you only want to change a certain part. This can be done using the following code, which uses str_replace() in the code :

    /**
     * Function for `woocommerce_customer_available_downloads` filter-hook.
     * 
     * @param  $downloads   
     * @param  $customer_id 
     *
     * @return 
     */
    function filter_woocommerce_customer_available_downloads( $downloads, $customer_id ) {
        // Only on my account downloads section
        if ( ! is_wc_endpoint_url( 'downloads' ) )
            return $downloads;
    
        // Loop though downloads
        foreach( $downloads as $key => $download ) {
            // Replace
            $downloads[$key]['download_url'] = str_replace( '/?download_file', '/account/downloads/?download_file', $download['download_url'] );
        }
    
        return $downloads;
    }
    add_filter( 'woocommerce_customer_available_downloads', 'filter_woocommerce_customer_available_downloads', 10, 2 );