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;
}
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 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 );