I have written a plugin which collects stats on document ready.

Keep in mind that my database table is already created.

I've added the following code to do the ajax code

add_action( 'wp_head', 'zkr_stats_ajax' );
function zkr_stats_ajax(){
?>
        <script type='text/javascript' >
        jQuery(document).ready(function() {
        //jQuery(window).load(function() {

                //set data varialbel with values


                var data = {
                        action: 'action_stats',
                        zkr_filename: '<?php echo $_SERVER['PHP_SELF']; ?>',
                        zkr_ip: '<?php echo $_SERVER['REMOTE_ADDR']; ?>',
                        zkr_referer: '<?php if(isset($_SERVER['HTTP_REFERER'])){ echo $_SERVER['HTTP_REFERER'];}else{ } ?>',
                        zkr_browser: '<?php echo $_SERVER['HTTP_USER_AGENT']; ?>',
                        zkr_method: '<?php echo $_SERVER['REQUEST_METHOD']; ?>'


                };

                var ajaxurl = '<?php admin_url('admin-ajax.php'); ?>'; // set the admin ajax url
                jQuery.post(ajaxurl, data, function(response) {

                });               

        });

        </script>
<?php
}

Then there is a function that handles the data being sent from the ajax above and stores the data into the mysql database table.

add_action('wp_ajax_nopriv_action_stats', 'zkr_stats_update'); //ajax callback
function zkr_stats_update(){
        global $wpdb;

        if(isset($_POST)){
        $filename = $_POST['zkr_filename'];

        $ip = $_POST['zkr_ip'];
        $referer = $_POST['zkr_referer'];
        $browser = $_POST['zkr_browser'];
        $method = $_POST['zkr_method'];



            $table_name = $wpdb->prefix . "zkr_stats";
            $row = $wpdb->get_results( "SELECT * FROM ".$table_name." WHERE ip = '$ip' ");
            if($wpdb->num_rows == 0){

                $num = 1;

                $wpdb->query( $wpdb->prepare( "INSERT INTO ". $wpdb->prefix ."zkr_stats(ip, filename, referer, browser, method, timestamp, number) VALUES('".$ip."', '".$filename."', '".$referer."', '".$browser."', '".$method."', NOW(), '".$num."')" )) or wp_die( 'Could not save data!' ); //insert new data if the current ip was not used before
            }
            elseif($wpdb->num_rows == 1){

            foreach($row as $rows){
            $num = $rows->number + 1;
            }
            $wpdb->query( $wpdb->prepare( "UPDATE ".$table_name." SET number = '".$num."' WHERE ip = '".$ip."'" ))or wp_die( 'Could not update data!' ); //update visit data for old ip

            }
        }





}

Now when the page loads, I can see in firebug that data is being posted via ajax, but nothing is getting saved.

Only when I add the function zkr_stats_update() to the header of the theme does it save but then it saves double, one empty and one with data.

What am I doing wrong?

Thanks guys

link|improve this question
Does adding exit; as the last line of zkr_stats_update() fix anything? – m0r7if3r Jan 31 at 13:53
I've added the exit; at the end of that function but nothing is going on. When I add the function to the header it stops executing and kills the rest of wordpress loading :( – Morne Zeelie Jan 31 at 14:03
Did you add it to the function, or after the function? It should come right after $wpdb->prepare(...) ) } }, before the final }...and it shouldn't stop anything from executing unless you are using the same function to handle things which are not ajax calls. – m0r7if3r Jan 31 at 14:07
Yes I added it in right there, at this part: – Morne Zeelie Jan 31 at 14:11
foreach($row as $rows){ $num = $rows->number + 1; } $wpdb->query( $wpdb->prepare( "UPDATE ".$table_name." SET number = '".$num."' WHERE ip = '".$ip."'" ))or wp_die( 'Could not update data!' ); //update visit data for old ip } } exit; } – Morne Zeelie Jan 31 at 14:11
show 3 more comments
feedback

3 Answers

The way you're using $wpdb->prepare doesn't help anything. You have to properly prepare the values and then add them like with sprintf as %s or %d.

Oh, and I don't believe "working with WP ajax for over a year.". In this case you would also know about the nopriv hooks for public usage :)

add_action( 'wp_ajax_nopriv_action_stats', ...
link|improve this answer
Thanks, but if you had looked at my code above in my question you will see that I was using the wp_ajax_nopriv like so add_action('wp_ajax_nopriv_action_stats', 'zkr_stats_update'); //ajax callback. So yes over a year dude! :) – Morne Zeelie Jan 31 at 15:47
Must have been a missread on my side :) Try to replace == with === to check if you've an integer in your if/elseif. – kaiser Jan 31 at 17:03
feedback

I think the issue is that if(isset($_POST)) is returning false and none of the code is being executed.

Try removing it or even better create a response variable to echo back to the Ajax so you can check it in Firebug.

if(isset($_POST)){
    $response = 'Post returned true';

// Your database code

  } else { $response = 'Post returned false'; }

echo $response;

die(1);
link|improve this answer
feedback

Ok I've solved the problem.

I had to change the ajaxurl to MyAjax.ajaxurl

                jQuery.post(MyAjax.ajaxurl, data, function(response) {

                });               

In my php code I had to add the following

function my_scripts_method() {
    wp_enqueue_script(  'jquery'  );
    // declare the URL to the file that handles the AJAX request (wp-admin/admin-ajax.php)
    wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}    
add_action('wp_enqueue_scripts', 'my_scripts_method');

Without doing the things above nothing worked, the most important part was the wp_localize_script part

I Hope this helps someone else when they get stuck?

Thanks for everyone's help even thou you could not completely help me out :)

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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