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