Search code examples
phpwoocommercehook-woocommercestorefrontchild-theming

Get download count of downloadable product to display in Woocommerce


I am hoping to display how many ppl hv downloaded the product, notice, not the number of sales. Because sometimes I will offer the product free, and I was hoping to manipulate this number with each click.

The first part I tried to display the number of downloads:

function add_download_count(){
    global $product;
    if ($product->is_downloadable('yes')){
$query = "SELECT SUM( download_count ) AS count FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = $product->id";
    $count = $wpdb->get_var( $query );
        echo "Downloads: ".$count;
    }
}
add_action("woocommerce_before_single_product_summary", "add_download_count");

I learnt this from another post here: Download Count on WooCommerce Free Product it's a very dated post so maybe something is changed now that I tried the code with with no avail because it returns an error: Call to a member function get_var() on null

Second Part, I hope to add the number of downloads by clicking the following:

foreach( $downloads as $key => $each_download ) {
  echo '<a href="'.$each_download["file"].'">Download</a>';
}

however I am not sure how to make that happen? I am thinking if it is possible to click and trigger to update a +1 to the download_count.

Or am I in the wrong logic here?


UPDATE

After tinkering a bit around, i found this method doesn't work.

not even putting global $wpdb; to it.

The reason for adding the number to download count after click is that:

user download through the link generated by $product->get_downloads() doesnt go through the cart system of WooCommerce.

thus it doesnt reflect automatically on the numbers of purchase or downloads.

I think this is bad logic and perhaps not a good way to achieve the idea. I move on and tried to utilize the default $product->get_total_sales() instead. This seemed to be a safer way and as intended by the original design.

I successfully display number of sales easily by:

function add_download_count(){
    global $product;
    $count = $product->get_total_sales();
    echo "<span id='downloadcount' data-downloadcount='".$count."'><span class='enclass'>Downloads:</span>&nbsp;".$count."</span>";
}
add_action("woocommerce_single_product_summary", "add_download_count", 15);

As you can see I tried to store the count number in data-count, so it can be manipulated through AJAX.


jQuery(document).ready(function($) {

    $( ".downloadbtn_now" ).click(function() {



    //aJAX
    let wasdownloadcount = parseInt($( "#downloadcount" ).data( "downloadcount" ) ) ;
    let downloadcount = wasdownloadcount + 1;
     $.ajax({
            type: "POST",url: "<? admin_url('admin-ajax.php') ?>",            
            dataType: "json",
            data: { downloadcount: downloadcount, action: 'download_count' }
          }).done(function() {
            alert( "Data was " + wasdownloadcount + " but now is: " +downloadcount );
          });

    });


});

I got:

POST http://localhost/wp-admin/admin-ajax.php 500 (Internal Server Error)

and I am not sure how to move forward from here.

my function call back in functions.php as follow, it uses the default function in woocommerce set_total_sales:

//AJAX
add_action('wp_ajax_download_count', 'download_count_callback');
 add_action('wp_ajax_nopriv_download_count', 'download_count_callback');
function download_count_callback(){
    $downloadcount = $_POST['downloadcount'];
set_total_sales($downloadcount);
    die();
}

Where's my problem?


Solution

  • function show_number_of_downloads() {
        global $wpdb, $product;
    
        $product_id = ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) ) ? $product->get_id() : 0;
    
        if ( empty( $product_id ) ) return;
    
        $product_type = ( is_object( $product ) && is_callable( array( $product, 'get_type' ) ) ) ? $product->get_type() : 'simple';
    
        if ( 'variable' === $product_type ) {
            $product_ids = $product->get_children();
        } else {
            $product_ids = array( $product_id );
        }
    
        $how_many_product_ids = count( $product_ids );
        $id_placeholder       = array_fill( 0, $how_many_product_ids, '%d' );
    
        $count = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT SUM( download_count ) AS count
                    FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
                    WHERE product_id IN (".implode( ',', $id_placeholder ).")",
                $product_ids
            )
        );
        if ( ! empty( $count ) ) {
            echo '<strong>' . esc_html__( 'Total downloads' ) . '</strong>: ' . $count;
        }
    }
    add_action( 'woocommerce_single_product_summary', 'show_number_of_downloads' );