1

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

So my php function to count post views working incorrectly.

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!

3 Answers 3

2

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);
}
3
  • Thanks @Emanuele - I will try again and tell you about the result. Jul 24, 2013 at 10:40
  • Hi @Emanuele, I was edit my Question again with your answer but still not working. I want to +1 view for current post & page, not use in archive loop. What's wrong I have again? Thank you very much! Jul 24, 2013 at 11:23
  • 1
    Add update take a look, let me know if it works @ZenNguyễn
    – iEmanuele
    Jul 24, 2013 at 11:40
0

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');
}
1
  • Honestly: Dumping random code into an answer is no answer. Please take your time to explain things step by step.
    – kaiser
    Jan 27, 2015 at 13:16
0

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');  
    }
1
  • Please use the WYSIWYG editor buttons to format your content. And: Please explain why this answer is helpful.
    – kaiser
    Jan 27, 2015 at 13:15

Your Answer

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

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