-5

I am creating a WordPress widget that shows and advert. When the advert is clicked I want to record the clicks with some detail.

The database table is already created and entries can be saved correctly using the function f1_add_advert_click($advert_id) in save-advert-click.php, which resides in the same directory as the Widget's PHP that I want to call it from (the plugin's root directory).

Requirements:

  • link will be on a piece of text, just a plain a href
  • a visitor should see the target link when he hovers his cursor over the link, not appended by a parameter for the next page
  • no 'middle' page that registers the click then redirects onto the target page. Just straight from the origin to the target.
  • secure: the advert ID is passed on to the f1_add_advert_click function and then inserted into the database. I would like to be sure that it's the correct ID (not something a visitor could change).
  • there can be multiple instances of this Widget on a page

I have seen and tried a lot of examples on Stackoverflow, but either I don't get it or the situation there is different from mine. Would gladly appreciate a well commented code example that works in my situation. Please be aware that I am not a seasoned programmer, especially 'green' when it comes to JavaScript and jQuery.

From what I have read on the web I think I should be using AJAX to first register the click, then send the browser to the target page. Not sure if I have to use onclick or not, based on the bottom answer of this post.

Have put in about four hours so far on this part. Now asking for help. Not much code to show, because I deleted everything that didn't work.

This is what I have currently got within the widget function of the plugin (left out the regular php showing title and so on):

<script type="text/javascript">
function myAjax() {
    $.ajax({
        type: "POST",
        url: './wp-content/plugins/facilitaire-advert-widget/save-advert-click.php',
        data:{action:'call_this'},
        success:function(html) {
            alert(html);
        }
    });
}
</script>

Followed by the link and the click action

<p><a href="" onclick="myAjax()" class="deletebtn">Link of Advert</a>

Then these are my contents for save-advert-click.php

// check for action signal
if($_POST['action'] == 'call_this') {
    f1_add_advert_click ();
}


/**
 * Records a click event in the database
 */
function f1_add_advert_click ()
{
    $advert_id = random_int(1,300); // change to $clicked_advert_id later
    $user_ip = get_user_ip();

    global $wpdb;
    $table_name = $wpdb->prefix . 'f1_advert_clicks';

    $wpdb->insert( $table_name, array(
        'advert_id'=> $advert_id,
        'user_agent'=> $_SERVER['HTTP_USER_AGENT'],
        'ip_address'=> $user_ip
        ),
        array(
            '%d',
            '%s',
            '%s'
        )
    );
}

/**
 * Get user IP
 */
function get_user_ip()
{
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if ( filter_var($client, FILTER_VALIDATE_IP) ) {
        $ip = $client;
    } elseif ( filter_var($forward, FILTER_VALIDATE_IP) ) {
        $ip = $forward;
    } else {
        $ip = $remote;
    }

    return $ip;
}

UPDATE WITH SOLUTION
Thanks to @mplungjan's suggestion I updated my code to the following, working code. Please note some differences with @mplungjan's code, because I had to make some adjustments to make it work in WordPress.

contents of bottom part of show-advert.php

<script>
jQuery(function() { 
    jQuery(".advertLink").on("click",function(e) { 
        e.preventDefault(); // stop the link unless it has a target _blank or similar
        var href = this.href;
        var id= <?php echo $advert_id; ?>;
        jQuery.post("<?php echo get_home_url(); ?>/wp-content/plugins/facilitaire-advert-widget/save-advert-click.php",
             { "action":"register_click", "advert_id":id },
             function() {
                 location=href;
             }
         );
    });
});
</script>

<a href="https://stackoverflow.com/" id="advert1" class="advertLink">Link of Advert</a><br />

<?php

Then in the top part of save-advert-click.php I have

<?php

// check for action signal
if($_POST['action'] == 'register_click') {
    f1_add_advert_click( $_POST["advert_id"] );
}

/**
 * Records a click event in the database
 */
function f1_add_advert_click ( $advert_id )
{
    $user_ip = get_user_ip();

    // need to load WordPress to be able to access the database
    define( 'SHORTINIT', true );
    require_once( '../../../wp-load.php' ); // localhost needs this, production can have require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );

    global $wpdb;
    $table_name = $wpdb->prefix . 'f1_advert_clicks';

    $wpdb->insert( $table_name, array(
        'advert_id'=> $advert_id,
        'user_agent'=> $_SERVER['HTTP_USER_AGENT'],
        'ip_address'=> $user_ip
        ),
        array(
            '%d',
            '%s',
            '%s'
        )
    );
}
Community
  • 1
  • 1
FreshSnow
  • 394
  • 2
  • 12
  • 3
    What have you done thus far? Please provide some code. – mferly Apr 12 '16 at 12:03
  • 2
    Welcome to SO. Please visit the [help] and take the [tour] to see what and how to ask. HINT: Post codes and efforts. If closed, the question can be re-opened after you have posted some more html and php – mplungjan Apr 12 '16 at 12:08
  • 1
    We would highly recommend you visit the help pages as mentioned by @mplungjan :-) – Matt D. Webb Apr 12 '16 at 12:15
  • Thanks for the suggestions. I went over the suggested pages and making edits to my original post now. – FreshSnow Apr 12 '16 at 12:31
  • Here is the [markdown help page](http://stackoverflow.com/editing-help). Hint: indent the full code 4 spaces from the left by selecting it and hitting the {} button – mplungjan Apr 12 '16 at 12:33

1 Answers1

0

You will want to do something like

$(function() { 
  $(".advertLink").on("click",function(e) { 
    e.preventDefault(); // stop the link unless it has a target _blank or similar
    var href = this.href;
    var id=this.id; // or $(this).data("advertid") if you have data-advertid="advert1" on the link
    $.post("./wp-content/plugins/facilitaire-advert-widget/save-advert-click.php",
       { "action":"call_this", "advert_ID":id },
       function() {
         location=href; // or window.open
       }
     );
  });
});

using

<a href="url_to_load" id="advert1" class="advertLink">Link of Advert</a>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Thanks @mplungjan! I have used your code example. Don't see entries in the db yet. I suppose it has to do with the way I pick up the variable in `save-advert-click.php`. It now has `f1_add_advert_click($parameter); 'function f1_add_advert_click ($ad_id) { $advert_id = $ad_id;` then the original rest. – FreshSnow Apr 12 '16 at 13:05
  • Yeah I did not use your parameters - I'll have a look in an hour – mplungjan Apr 12 '16 at 13:54
  • Updated to use your parameters exactly – mplungjan Apr 12 '16 at 14:49
  • Thanks again @mplungjan I have changed my code but did not get it to work yet. Can you please have another look? – FreshSnow Apr 12 '16 at 20:50
  • Any errors in the console (F12) can you call the post using a simple form? Why not take the ID from the link instead of using a random thing? I am off to bed – mplungjan Apr 12 '16 at 21:06
  • WOW! Finally did it! Updated code above now works!
    Found an error in my code with the ID. That's sorted now. Then there was an error in the console with the $ referring to jQuery. Since jQuery in WP runs in noConflict mode, I had to replace it with jQuery. Then I found out that because `save-advert-click.php` lives outside of PHP I had to get wp-load involved. Added `get_home_url()` to make sure the link to `save-advert-click.php` worked from all pages, not just home. Ad finally had to learn how to get variables that are posted to a page with `$_POST["variable"]`. Thanks again!
    – FreshSnow Apr 13 '16 at 18:03