Search code examples
wordpresswoocommerceproductmp3playback

Remove add to cart button on WooCommerce single product page if product has been purchased and show MP3 player instead


We have a WooCommerce store that sells files (MP3/MP4) to registered users and enables the user to play them in the "Downloads" section of their account (we have modified order-downloads.php).

The challenge we are facing is that we would like to enable user to play the MP3 also on the specific product page of the product that they have already purchased (instead of the "Add to cart" button, we would like to show the player if the user is logged in and has previously purchased this product).

I have found various solutions on how to prevent user to buy the same product again, however I don't know how I can combine the code from order-downloads.php and the product template to do this.

So far this is my code attempt, but unfortunately without the desired result. Anyone who can point me in the right direction?

add_filter( 'woocommerce_loop_add_to_cart_link', 'customizing_add_to_cart_button', 10, 2 );

function customizing_add_to_cart_button( $link, $product ){

    $bought = false;

    if( is_user_logged_in() ){
        $customer_orders = get_posts( array(
            'numberposts' => -1,
            'meta_key'    => '_customer_user',
            'meta_value'  => get_current_user_id(),
            'post_type'   => 'shop_order', // WC orders post type
            'post_status' => 'wc-completed' // Only orders with status "completed"
        ) );

        // Going through each current customer orders
        foreach ( $customer_orders as $customer_order ) {
            $order = wc_get_order( $customer_order->ID );
            // Going through each current customer order items
            foreach($order->get_items() as $item_id => $item_values){
                if($item_values['product_id'] == $product->id){
                    $bought = true;
                    break;
                }
            }
        }
    }

    if($bought){
       global $product;
       $downloads = array();
       $user_id = get_current_user_id();
       $downloads = wc_get_customer_available_downloads($user_id);

           if (!empty($downloads)) {
               foreach ($downloads as $download) {
               if ($download['product_id'] === $product->get_id()) {
                 $thelink = $download['download_url'];
               }
        }
    }
     /* $add_to_cart_url = site_url($thelink); */
        $button_text =  __('[audio src='.$thelink.']', 'woocommerce');

    } else {
        $add_to_cart_url = $product->add_to_cart_url();
        $button_text =  $product->add_to_cart_text();
    }

    $link = sprintf( '<a href="%s" rel="nofollow" data-product_id="%s" data-product_sku="%s" data-quantity="%s" class="button product_type_%s">%s</a>',
        esc_url( $add_to_cart_url ),
        esc_attr( $product->id ),
        esc_attr( $product->get_sku() ),
        esc_attr( isset( $quantity ) ? $quantity : 1 ),
        esc_attr( $product->product_type ),
        esc_html( $button_text )
    );
    return $link;
}

Solution

  • There are multiple ways to hide/replace an add to cart button in WooCommerce. It's a matter of figuring out which hooks are most suitable for your question.

    Since you don't just want to hide the add to cart button, but want to do this based on a few conditions, we will first apply a custom function that performs several checks:

    • If user is logged in
    • If product type is simple
    • If the product has already been purchased
    • If the product contains a downloadable mp3 file

    If all those conditions are met, we return the file url, if NOT, we return an empty string:

    function multiple_checks() {
        // Initialize
        $url_file = '';
    
        // Retrieve the current user object.
        $current_user = wp_get_current_user();
    
        if ( $current_user->ID == 0 ) return $url_file;
    
        global $product;
        
        // Is a WC product
        if ( is_a( $product, 'WC_Product' ) ) {
            // Only for simple products
            if ( $product->get_type() != 'simple' ) return $url_file;
    
            // Has bought
            if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->get_id() ) ) {
                // NOT has downloads
                if ( ! $product->is_downloadable() ) {
                    return $url_file;
                } else {
                    // Loop through WC_Product_Download objects
                    foreach ( $product->get_downloads() as $key_download_id => $download ) {
                        // Only for MP3 file
                        if ( $download->get_file_extension() == 'mp3' ) {                       
                            // Get url
                            $url_file = $download->get_file();
    
                            // Break loop
                            break;
                        }
                    }
                }
            }
        }
    
        return $url_file;
    }
    

    Then it is just a matter of calling the function, from the desired page and the desired display.


    For the single product page:

    function action_woocommerce_single_product_summary() {
        // Call function
        $url_file = multiple_checks();
    
        // NOT empty
        if ( ! empty ( $url_file ) ) { 
            // Hide prices
            remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
    
            // Removing add to cart button and quantities
            remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
    
            // New ouput
            echo "<div id='content' class='fancybox-hide' style='min-width:450px; min-height:250px;'>";
            echo do_shortcode( '[audio src="' . $url_file . '"]' );
            echo "</div>";
            echo "<a href='#content' class='ari-fancybox'>Listen to MP3</a>";
        }
    }
    add_action( 'woocommerce_single_product_summary', 'action_woocommerce_single_product_summary', 29 );
    

    For shop and archives pages:

    function filter_woocommerce_loop_add_to_cart_link( $sprintf, $product, $args ) {
        // Call function
        $url_file = multiple_checks();
    
        // NOT empty
        if ( ! empty ( $url_file ) ) { 
            // Setting
            $button_text = __( 'Your text', 'woocommerce' );
            
            // Single product Url
            $button_link = $product->get_permalink();
            
            // New link + text
            $sprintf = sprintf(
                '<a href="%s" class="%s">%s</a>',
                esc_url( $button_link ),
                esc_attr( isset( $args['class'] ) ? $args['class'] : 'button' ),
                esc_html( $button_text )
            );
        }
        
        return $sprintf;
    }
    add_filter( 'woocommerce_loop_add_to_cart_link', 'filter_woocommerce_loop_add_to_cart_link', 10, 3 );