Skip to content

Instantly share code, notes, and snippets.

@khromov
Last active April 13, 2023 17:36
Show Gist options
  • Save khromov/48218f5ce35cbb6b2e65 to your computer and use it in GitHub Desktop.
Save khromov/48218f5ce35cbb6b2e65 to your computer and use it in GitHub Desktop.
Count post view counts in WordPress via AJAX (Compatible with caching plugins)
<?php
/*
Plugin Name: Simple Popular Posts Lite
Plugin URI: -
Description: -
Version: 2015.03.01
Author: khromov
Author URI: http://snippets.khromov.se
License: GPL2
*/
/**
* Class Simple_Popular_Posts
*/
class Simple_Popular_Posts
{
public static $td = 'spp';
public static $post_types = array('post'); //,'page'
/**
* Constructor sets up all our hooks
*/
function __construct()
{
add_action('wp_footer', array(&$this, 'footer_script'), 999);
add_filter('query_vars', array(&$this, 'query_vars'));
add_action('wp', array(&$this, 'count'));
}
/**
* Adds counting code to footer
*/
function footer_script()
{
if((is_single() || is_attachment() || is_page() || is_singular()) && in_array(get_post_type(get_the_ID()), $this::$post_types)) :
?>
<script async type="text/javascript">
function SimplePopularPosts_AddCount(id, endpoint)
{
var xmlhttp;
var params = "/?spp_count=1&spp_post_id=" + id + "&cachebuster=" + Math.floor((Math.random() * 100000));
if (window.XMLHttpRequest)
xmlhttp = new XMLHttpRequest();
else
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
//alert(xmlhttp.responseText);
}
};
xmlhttp.open("GET", endpoint + params, true);
xmlhttp.send();
}
SimplePopularPosts_AddCount(<?php echo get_the_ID(); ?>, '<?php echo get_site_url(); ?>');
</script>
<?php
endif;
}
/**
* Adds our special query var
*/
function query_vars($query_vars)
{
$query_vars[] = 'spp_count';
$query_vars[] = 'spp_post_id';
return $query_vars;
}
/**
* Count function
*
* TODO: This should be doable with SHORTINIT and would be much faster
*/
function count()
{
/**
* Endpoint for counting visits
*/
if(intval(get_query_var('spp_count')) === 1 && intval(get_query_var('spp_post_id')) !== 0)
{
//JSON response
header('Content-Type: application/json');
$id = intval(get_query_var('spp_post_id'));
$current_count = get_post_meta($id, '_spp_count', true);
if($current_count === '')
$count = 1;
else
$count = intval($current_count)+1;
//Update post meta
update_post_meta($id, '_spp_count', $count);
echo json_encode(array('status' => 'OK', 'visits' => intval($current_count)+1));
}
}
}
$simple_popular_posts = new Simple_Popular_Posts();
@khromov
Copy link
Author

khromov commented Sep 28, 2020

@daro2013

It should work. To use it in your theme you need to use the following frontend code on your single-post.php / single.php / etc template:

<?php echo (int)get_post_meta(get_the_ID(), '_spp_count', true); ?>

Or if you're happy prepending it to each post using functions.php, something like:

add_filter('the_content', function($content) {
    $prepend = "<span>" . get_post_meta(get_the_ID(), '_spp_count', true) . "</span>"
    return $prepend . $content;
});

@daro2013
Copy link

Hi sir,

It does not work. It only show 0 views.

@khromov
Copy link
Author

khromov commented Sep 29, 2020

@daro2013

I suggest you perform basic troubleshooting (javascript errors, response from Ajax call, etc.)

If you can't make it work, try a plugin like Koko Analytics.

@murugeasamgr
Copy link

cool guys.. just replace line number 37 from<script type="text/javascript"> to <script async type="text/javascript">. it is working on my site.

@khromov
Copy link
Author

khromov commented Apr 13, 2023

@murugeasamgr Thanks, I updated the gist. It's really old, it could be rewritten to use fetch as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment