Update Custom post field by Ajax on cached site

My site cached by “wp-supper cache” plugin and “cloudflare.com”

So my php function to count post views working incorrectly.

Read More

I try to use ajax for it but I’m noob with JS code so I can not know where is wrong.

In functions.php I create a simple function:

add_action('template_redirect', 'ajax_activation');
function ajax_activation(){
   //optional 
   wp_enqueue_script( 
      'ajax_script', 
       get_template_directory_uri() . '/js/ajax.js', // path to your js file for ajax operations
       array( 'jquery' ), false
   );
   //end optional
   wp_localize_script( 
      'ajax_script', // the name of your global.js registered file
      'ajax_object', // name 
       array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) // you can add other items for example for using a translated string in javascript/jquery context
   ); 
}

add_action('wp_ajax_get_PostViews', 'get_PostViews');
add_action('wp_ajax_nopriv_get_PostViews', 'get_PostViews');

function get_PostViews() {
$id = isset( $_POST['id'] ) ? $_POST['id'] : false;
$count_key = 'post_views_count'; 
$count = get_post_meta($post_ID, $count_key, true);
if( empty($count) ){ $count = 1; } else { $count++; }
update_post_meta($post_ID, $count_key, $count);
}

Code in ajax.js file:

var postID = $(".view_detail").attr("id");
jQuery.ajax({
    type: "POST",
    url: ajax_object.ajaxurl, // this is the object you defined in function.php
    data: {
       action: 'get_PostViews', // the name of your function
       id: postID // you can store it in html attribute for an easy access like: jQuery(element).attr('id');
    },
    success: function (result) {
    }
});

The page.php in my theme:

<div id="<?php the_ID(); ?>" <?php post_class('view_detail'); ?>>

Please tell me how can I do it work? Thank you very much!

Related posts

3 comments

  1. I’ve spotted some errors here:

    jQuery.ajax({
         type: "POST",
         contentType: "application/json; charset=utf-8", // default: 'application/x-www-form-urlencoded; charset=UTF-8'. you can not set
         url: "http://localhost/wp-admin/admin-ajax.php", // if you have correctly enabled ajax in wp, you should use the object you set up with the url
         data: "{'action':'get_PostViews(" + idpost + ")'}", // you can use a PlainObject notation, so you don't need to double quoted. action property is the name of your function as you written in function.php
         success: function (result) {
           alert('Update Success!');
         }
    });
    

    Take a look here jQuery.ajax() .
    To use ajax within WordPress follow these steps:

    1. enable ajax functionality
    2. declare your function in function.php
    3. use javascript/jquery to send data to server and to listen data
      retrieved

    Enabling ajax

    The best way to accomplish that ( in my opinion ) is:

    //File functions.php
        add_action('template_redirect', 'ajax_activation');
        function ajax_activation(){
           //optional 
           wp_enqueue_script( 
              'ajax_script', 
               get_template_directory_uri() . '/js/jquery.ajax.js', // path to your js file for ajax operations
               array( 'jquery' ), false
           );
           //end optional
           wp_localize_script( 
              'ajax_script', // the name of your global.js registered file
              'ajax_object', // name 
               array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) // you can add other items for example for using a translated string in javascript/jquery context
           ); 
        }
    

    Declare function

    //File functions.php
    add_action('wp_ajax_get_PostViews', 'get_PostViews');
    add_action('wp_ajax_nopriv_get_PostViews', 'get_PostViews');
    
    function get_PostViews() {
        $id = isset( $_POST['id'] ) ? $_POST['id'] : false;
        // your code here
        wp_die(); // | die(); you need this to avoid trailing zero
    }
    

    jQuery/Javascript

    $.ajax({
        type: "POST",
        url: ajax_object.ajaxurl, // this is the object you defined in function.php
        data: {
           action: 'get_PostViews', // the name of your function
           id: // you can store it in html attribute for an easy access like: jQuery(element).attr('id');
        },
        success: function (result) {
    
        }
    });
    

    I guess you are using this function for all posts in a loop, you can call ajax once to do the work for all posts.
    For example i want to retrieve with ajax the titles of my posts:

    HTML

    <html>
    <!-- some stuff here -->
    <h3 id="<?php echo get_the_ID(); ?>" class="spyhole"></h3> <!-- there are many of this :  ) -->
    <!-- some stuff here -->
    </html>
    

    jQuery

    ids = [];
    items = $('.spyhole');
    $.each( items, function( i, v){
        ids.push( $(v).attr( 'id' ) ); // each value is added to array
    });
    $.ajax({
        type: "POST",
        url: ajax_object.ajaxurl,
        data: {
          action: 'getMyTitleAjax',
          id: ids
        },
        success: function (result) {
          data = $.parseJSON( result ); // Takes a well-formed JSON string and returns the resulting JavaScript object.
          $.each( data, function( i, v ){
            $('.spyhole[id="' + i + '"]').html( v ); // print the title
          });
        }
    });
    

    PHP

    // Enabling ajax - functions.php
    add_action('template_redirect', 'ajax_activation');
    function ajax_activation(){
       //optional 
       wp_enqueue_script( 
          'ajax_script', 
           get_template_directory_uri() . '/js/jquery.ajax.js', // path to your js file for ajax operations
           array( 'jquery' ), false
       );
       //end optional
       wp_localize_script( 
          'ajax_script', // the name of your global.js registered file
          'ajax_object', // name 
           array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) // you can add other items for example for using a translated string in javascript/jquery context
       ); 
    }
    
    // Declare my function
    add_action('wp_ajax_getMyTitleAjax', 'getMyTitleAjax', 3);
    add_action('wp_ajax_nopriv_getMyTitleAjax', 'getMyTitleAjax', 3);
    function getMyTitleAjax() {
        $ids = isset( $_POST['id'] ) ? $_POST['id'] : false; // check if there is something in global $_POST
        if( $ids && is_array( $ids ) ){
          foreach( $ids as $id ){
            $titles[$id] = get_the_title( $id ); 
          }
        }
        echo json_encode( $titles ); // prints the result
        wp_die(); // avoid trailing zero
    }
    

    Hope it helps, if something is not clear feel free to ask

    Update

    According to your question updates, change this:

    function get_PostViews() {
    $id = isset( $_POST['id'] ) ? $_POST['id'] : false;
    $count_key = 'post_views_count'; 
    $count = get_post_meta($post_ID, $count_key, true);
    if( empty($count) ){ $count = 1; } else { $count++; }
    update_post_meta($post_ID, $count_key, $count);
    }
    

    with this:

    function get_PostViews() {
    $id = isset( $_POST['id'] ) ? $_POST['id'] : false;
    $count_key = 'post_views_count'; 
    $count = get_post_meta($id, $count_key, true);
    if( empty($count) ){ $count = 1; } else { $count++; }
    update_post_meta($id, $count_key, $count);
    }
    
  2. single.php

    // ------------Post  views----------          
    <script type="text/javascript">
        // get post views
        (function($) {
            function mostViews() {
                 $.getJSON("<?php bloginfo('template_directory'); ?>/ajax.php",
                        {
                            action: 'get_mostViewedPost',
                            postid: <?php echo get_the_ID() ?>
                        }, function (data) {
                        })
            }
            var mostViews = new mostViews();
        })(jQuery);
    
    </script>
    

    functions.php

    // ------------Post  views----------
    // function to display number of posts.
    function getPostViews($postID){
        $count_key = 'post_views_count';
        $count = get_post_meta($postID, $count_key, true);
        if($count==''){
            delete_post_meta($postID, $count_key);
            add_post_meta($postID, $count_key, '0');
            return "0 View";
        }
        return $count.' Views';
    }
    
    // function to count views.
    function setPostViews($postID) {
        $count_key = 'post_views_count';
        $count = get_post_meta($postID, $count_key, true);
        if($count==''){
            $count = 0;
            delete_post_meta($postID, $count_key);
            add_post_meta($postID, $count_key, '0');
        }else{
            $count++;
            update_post_meta($postID, $count_key, $count);
        }
    }
    
    // Add it to a column in WP-Admin
    add_filter('manage_posts_columns', 'posts_column_views');
    add_action('manage_posts_custom_column', 'posts_custom_column_views',5,2);
    function posts_column_views($defaults){
        $defaults['post_views'] = __('Views');
        return $defaults;
    }
    function posts_custom_column_views($column_name, $id){
        if($column_name === 'post_views'){
            echo getPostViews(get_the_ID());
        }
    }
    
    function postViews_callback(){
        setPostViews($_GET['postid']) ;
        echo "Success, Post id: ".$_GET['postid'];
        die();
    }
    add_action('ajax_get_mostViewedPost', 'postViews_callback');
    add_action('ajax_nopriv_get_mostViewedPost', 'postViews_callback');
    
    // -----------end Post views----------
    

    ajax.php

    <?php
    //mimic the actuall admin-ajax
    define('DOING_AJAX', true);
    
    //make sure you update this line
    //to the relative location of the wp-load.php
    
    require_once(dirname(dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])))) . '/wp-load.php');
    //Typical headers
    header('Content-Type: text/html');
    send_nosniff_header();
    
    //Disable caching
    header('Cache-Control: no-cache');
    header('Pragma: no-cache');
    
    $action = esc_attr(trim($_GET['action']));
    
    
    //A bit of security
    $allowed_actions = array( 
        'get_mostViewedPost'
    );
    
    //For logged in users 
    add_action('ajax_get_mostViewedPost', 'postViews_callback');
    //For guests 
    add_action('ajax_nopriv_get_mostViewedPost', 'postViews_callback');
    
    if(in_array($action, $allowed_actions)) {
        if(is_user_logged_in())
            do_action('ajax_'.$action);
        else
            do_action('ajax_nopriv_'.$action);
    } else {
        die('-1');
    }
    
  3. single.php //post views

       <script type="text/javascript">  
            // get post views  
            (function($) {  
                function mostViews() {  
                     $.getJSON("<?php bloginfo('template_directory'); ?>/ajax.php",  
                            {  
                                action: 'get_mostViewedPost',  
                                postid: <?php echo get_the_ID() ?>  
                            }, function (data) {  
                            })  
                }  
                var mostViews = new mostViews();  
            })(jQuery);  
    
        </script>
    

    functions.php

    // ------------Post  views----------  
    // function to display number of posts.  
    function getPostViews($postID){  
        $count_key = 'post_views_count';  
        $count = get_post_meta($postID, $count_key, true);  
        if($count==''){  
            delete_post_meta($postID, $count_key);  
            add_post_meta($postID, $count_key, '0');  
            return "0 View";  
        }  
        return $count.' Views';  
    } 
    // function to count views.  
    function setPostViews($postID) {  
        $count_key = 'post_views_count';  
        $count = get_post_meta($postID, $count_key, true);  
        if($count==''){  
            $count = 0;  
            delete_post_meta($postID, $count_key);  
            add_post_meta($postID, $count_key, '0');  
        }else{  
            $count++;  
            update_post_meta($postID, $count_key, $count);  
        }  
    } 
    
    // Add it to a column in WP-Admin  
    add_filter('manage_posts_columns', 'posts_column_views');  
    add_action('manage_posts_custom_column', 'posts_custom_column_views',5,2);  
    function posts_column_views($defaults){  
        $defaults['post_views'] = __('Views');  
        return $defaults;  
    } 
    function posts_custom_column_views($column_name, $id){  
        if($column_name === 'post_views'){  
            echo getPostViews(get_the_ID());  
        }  
    } 
    function postViews_callback(){  
        setPostViews($_GET['postid']) ;  
        echo "Success, Post id: ".$_GET['postid'];  
        die();  
    }  
    add_action('ajax_get_mostViewedPost', 'postViews_callback');  
    add_action('ajax_nopriv_get_mostViewedPost', 'postViews_callback'); 
    
    // -----------end Post views----------  
    

    ajax.php

     <?php  
        //mimic the actuall admin-ajax  
        define('DOING_AJAX', true);  
    
    
    
        //make sure you update this line  
        //to the relative location of the wp-load.php  
    
        require_once(dirname(dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])))) . '/wp-load.php');
        //Typical headers  
        header('Content-Type: text/html');  
        send_nosniff_header();  
    
        //Disable caching  
        header('Cache-Control: no-cache');  
        header('Pragma: no-cache');  
    
        $action = esc_attr(trim($_GET['action']));  
    
    
        //A bit of security  
        $allowed_actions = array(   
            'get_mostViewedPost'
        );  
    
        //For logged in users   
        add_action('ajax_get_mostViewedPost', 'postViews_callback');  
        //For guests 
        add_action('ajax_nopriv_get_mostViewedPost', 'postViews_callback');
    
        if(in_array($action, $allowed_actions)) {  
            if(is_user_logged_in())  
                do_action('ajax_'.$action);  
            else  
                do_action('ajax_nopriv_'.$action);  
        } else {  
            die('-1');  
        }
    

Comments are closed.