I am building wordpress web site, which will have an option to download zip file from certain custom post type. By clicking on download button, user automatically starts with downloading zip file.

<a id="countable_link" href="#">download</a>

My goal is to display the number of downloads next to the very same button. So far everything is working well, except the fact that I am able to trigger counter infinity number of times.

Instead of it, i would like that counter can be executed only once by the unique user. I am assuming that this has to do something with users ip address, but my knowledge of PHP, SQL and ajax is extremely poor.

Here is the script that i have found: (it has also been posted here)


if ( is_admin() ) add_action( 'wp_ajax_nopriv_link_click_counter',  'link_click_counter' );
function link_click_counter() {

    if ( isset( $_POST['nonce'] ) &&  isset( $_POST['post_id'] ) && wp_verify_nonce( $_POST['nonce'], 'link_click_counter_' . $_POST['post_id'] ) ) {
      $count = get_post_meta( $_POST['post_id'], 'link_click_counter', true );
      update_post_meta( $_POST['post_id'], 'link_click_counter', ( $count === '' ? 1 : $count + 1 ) );

add_action( 'wp_head', 'link_click_head' );
function link_click_head() {
    global $post;

    if( isset( $post->ID ) ) {
   <script type="text/javascript" >
   jQuery(function ($) {
      var ajax_options = {
        action: 'link_click_counter',
        nonce: '<?php echo wp_create_nonce( 'link_click_counter_' . $post->ID ); ?>',
        ajaxurl: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
        post_id: '<?php echo $post->ID; ?>'

     $( '#countable_link' ).on( 'click ', function() {
        var self = $( this );
        $.post( ajax_options.ajaxurl, ajax_options, function() {
           window.location.href = self.attr( "href" );
       return false;

When I put this snippet into my functions.php file, it generates custom field value with exact number of clicks. Would be great if these numbers are more realistic. For example, if it displays value of 350 , people would really like to know that 350 different users downloaded the content.

I am grateful for any solution beside using additional plugins. If somehow can be incorporated into this snippet, it will just end up circle perfect for me.


1 Answer 1


What would you do if the user uses a proxy and randomizes his IP address? There are numerous browser plugins to simplify that to a click of a button to download multiple times. The same goes for cookies. Aside from that you are trying to collect data that allows to identify users, which is illegal in lots of countries.

What (could) work much better is a disposable hash that you add as post meta data. Example that adds such a hash during publishing a post - in this case the md5 hashed post date as UNIX time stamp:

add_action( 'draft_to_publish', function( \WP_Post $post )
        md5( date( 'U', $post->post_date ), 
} );

(You can construct your hash however you want).

Then, when a user downloads a file, simply set a user meta value with that hash as key and a value of 1/true/foo. Upon download, you just check if the current download_hash is already a user meta value and then can deny the download.

To implement a counter, you would simply add another attachment meta value named download_users where you save an array of user IDs. Done.

  • Thank you for the effort, but i really cant understand this. Can you help me more with this, where and what should i put ? I Don't wanna bother you if there is no simple way to incorporate this into what i need.
    – gundra
    Commented Feb 24, 2015 at 20:19
  • The first part is already done. I just don't have the time right now to write a full plugin. Just try to fill in the bits. Try, fail, update your question, show how far you came and where you failed.
    – kaiser
    Commented Feb 24, 2015 at 20:40
  • 1
    Thanks Kaiser, will do. I'll spend some time with it, and see where it will take me. Cheers
    – gundra
    Commented Feb 24, 2015 at 20:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.