Skip to content

Instantly share code, notes, and snippets.

@hieu-tn
Created September 15, 2020 04:31
Show Gist options
  • Save hieu-tn/1fce2c0395c7badcc899259841786847 to your computer and use it in GitHub Desktop.
Save hieu-tn/1fce2c0395c7badcc899259841786847 to your computer and use it in GitHub Desktop.
WP Postview log
<?php
/**
* WordPress basically doesn't support how many views a post has. Therefore, we need to undertake our own implementation.
*
**/
require_once get_stylesheet_directory() . '/postview_log.php';
PostViewLog::get_instance();
//To keep the count accurate, lets get rid of prefetching
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
function ahyhy_set_post_views( $post_id ) {
$postview_log = \my_namespace\PostViewLog::get_instance();
$postview_log->set_post_view( $post_id );
}
function ahyhy_track_post_views( $post_id ) {
if ( !is_single() ) return;
global $post;
if ( get_post_status($post) === 'publish' ) $post_id = $post->ID;
ahyhy_set_post_views( $post_id );
}
add_action( 'wp_head', 'ahyhy_track_post_views');
function ahyhy_update_postview_log( $post_id, $post, $update ) {
// Only set for post_type = post!
if ( 'post' !== $post->post_type ) return;
$postview_log = \my_namespace\PostViewLog::get_instance();
$postview_log->set_post_status( $post, $post->post_status );
}
add_action( 'save_post', 'ahyhy_update_postview_log', 10, 3 );
// E.g get most viewed posts this week
function ahyhy_get_this_week_most_viewed_posts( $number_of_posts = 5, $offset = 0 ) {
$d = strtotime('today');
$start_week = strtotime( 'last monday midnight', $d );
$end_week = strtotime( 'next sunday', $d );
$start_week = date('Y-m-d', $start_week );
$end_week = date( 'Y-m-d', $end_week );
$post_ids = \my_namespace\PostViewLog::get_instance()->get_most_viewed_posts_in_period( $start_week, $end_week, $number_of_posts, $offset );
$the_query = new WP_Query( array(
'posts_per_page' => $number_of_posts,
'post__in' => $post_ids,
'ignore_sticky_posts' => true,
'orderby' => 'post__in'
) );
return $the_query;
}
// get 5 most viewed posts this week
// $most_viewed_posts = ahyhy_get_this_week_most_viewed_posts();
<?php
/**
* @package my_package
*/
namespace my_namespace;
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
class PostViewLog {
private static $instance = null;
private $table_name = 'postview_logs';
private $wpdb = null;
/**
* @return PostViewLog|null
*/
public static function get_instance() {
if (is_null(self::$instance))
self::$instance = new PostViewLog();
return self::$instance;
}
/**
* PostViewLog constructor.
*/
private function __construct() {
global $wpdb;
$table_name = $wpdb->prefix . $this->table_name;
$this->wpdb = $wpdb;
$this->table_name = $table_name;
$table_post = $wpdb->prefix . 'posts';
$charset_collate = $wpdb->get_charset_collate();
$sql_create = "CREATE TABLE $table_name (
ID BIGINT NOT NULL AUTO_INCREMENT,
post_id BIGINT UNSIGNED NOT NULL,
post_status varchar(20) DEFAULT 'publish' NOT NULL,
views_count MEDIUMINT DEFAULT 0 NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP,
INDEX (post_id),
FOREIGN KEY (post_id) REFERENCES $table_post(ID) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(ID)
) $charset_collate;";
maybe_create_table($table_name, $sql_create);
}
/**
* @param null $post
* @param int $views
* @param null $date
* @return bool|false|int
*/
public function set_post_view( $post = null, $views = 1, $date = null ) {
$post = get_post( $post );
if( ! $post ) return false;
if( ! $views ) return false;
$date = current_time('Y-m-d');
$res = $this->wpdb->get_row( "SELECT * FROM $this->table_name WHERE post_id = $post->ID AND DATE(created_at) = '$date'" );
if ( is_null($res) )
return $this->wpdb->insert(
$this->table_name,
array(
'post_id' => $post->ID,
'views_count' => $views,
),
array(
'%s',
'%d',
)
);
return $this->wpdb->query( $this->wpdb->prepare( "UPDATE $this->table_name SET views_count = %d WHERE post_id = %d AND post_status = 'publish' AND DATE(created_at) = %s", absint($res->views_count) + $views, $post->ID, $date ) );
}
/**
* @param null $from
* @param null $to
* @param int $number_of_posts
* @return array|object|void|null
*/
public function get_most_viewed_posts_in_period( $from = null, $to = null, $number_of_posts = 8, $offset = 0 ) {
if ( is_null($from) || is_null( $to) || ! is_numeric($number_of_posts) || ! is_numeric($offset) ) return array();
if ( ! \DateTime::createFromFormat( 'Y-m-d', $from ) || ! \DateTime::createFromFormat( 'Y-m-d', $to ) ) return array();
$sql = "SELECT post_id FROM $this->table_name WHERE post_status = 'publish' AND DATE(created_at) > '$from' AND DATE(created_at) < '$to' ORDER BY views_count DESC";
$number_of_posts = absint($number_of_posts);
if ( $number_of_posts ) :
$sql .= " LIMIT $number_of_posts";
$offset = absint($offset);
if ( $offset ) $sql .= " OFFSET $offset";
endif;
$results = $this->wpdb->get_results( $sql );
if ( is_null($results) ) return array();
$post_ids = array();
foreach( $results as $row ) :
array_push( $post_ids, absint($row->post_id) );
endforeach;
return $post_ids;
}
/**
* @param $post
* @param string $post_status
* @return bool|false|int
*/
public function set_post_status( $post, $post_status = '' ) {
$post = get_post( $post );
if( ! $post ) return false;
return $this->wpdb->update(
$this->table_name,
array(
'post_status' => $post_status
),
array(
'post_id' => $post->ID
),
array(
'%s'
),
array(
'%d'
)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment