目前,我认为没有办法做到这一点,因为您没有很好的参考来获取基于日期的统计数据。
Notice:您正在按如下方式存储post视图:
add_post_meta($postID, $count_key, \'0\');
为了能够获取“最受关注的时期”,您必须做一些更复杂的事情,可能需要一个额外的数据库表。现在,视图的数量与任何时间段都没有关系。
例如,如果在数据库中创建了下表:
{$prefix} 应使用wordpress数据库表前缀(例如wp\\uu1)
CREATE TABLE {$prefix}post_views (
post_id bigint(20) NOT NULL,
entry_day datetime NOT NULL,
num_views int NOT NULL,
PRIMARY KEY (post_id,entry_day),
KEY idx_pv_ed (entry_day)
);
使用该表,您现在可以跟踪一段时间内的最高职位。
下面是作为类编写的修订版本,其中包含日志记录、错误处理和一个示例使用脚本,以显示正在发生的情况。
The Handler Class
下面的代码是一个小类,其中包含调试信息,以便您可以查看问题所在。
我在上面撒了笔记来解释发生了什么
class My_Most_Viewed_Posts {
protected $errors = null;
protected $notices = null;
protected $debug = false;
# This just sets up the errors, notices, and debug variables able
function __construct($debug = false) {
$this->clear_all();
if ( $debug ) {
$this->debug = true;
}
}
# This lets you add notices about what is going on so you can display them later
protected function add_notice($msg = \'\') {
if ( is_array($msg) || is_object($msg) ) {
$this->notices[] = print_r($msg, true);
} else {
$this->notices[] = $msg;
}
}
# Get an array of the most viewed posts as an array of the form ( post_id => number_of_views )
# - $oldest_date : should be of the form YYYY-MM-DD
# - $newest_date : should be of the form YYYY-MM-DD ( if null is provided, it will default to the current day )
# - $num_to_get : the number of results to return (e.g. 4 highest by default)
function get_highest_posts_in_range( $oldest_date, $newest_date = null, $num_to_get = 4 ) {
# Set up our return value
$found = array();
# Debug notice noting what was passed in
if ( $this->debug ) {
$this->add_notice( "Starting get_highest_posts_in_range( \'{$oldest_date}\', \'{$newest_date}\', {$num_to_get} )" );
}
# Do all real processing in a try / catch block to ensure can log problems instead of just throwing errors
try {
# Get a handle to the global database connection
global $wpdb;
# Verify that the provided $oldest_date is 10 characters long
if ( 10 !== strlen($oldest_date) ) {
throw new Exception("Parameter 1: Must be of the form YYYY-MM-DD", 10001);
} else {
# Appends time to the oldest date to make any between query include everything on the date
$oldest_date .= \' 00:00:00\';
}
# Initialize the $newest_date variable OR validate that any non null value could be in the right format
if ( is_null( $newest_date ) ) {
$newest_date = date(\'Y-m-d\') . \' 23:59:59\';
} else if ( 10 !== strlen( $newest_date ) ) {
# Error
throw new Exception("Parameter 2: Must be null or in the form YYYY-MM-DD", 10002);
} else {
# Appends time to make any between query contain everything entered that day
$newest_date .= \' 23:59:59\';
}
# Make sure that the number of records to get is sane
$num_to_get = (int) $num_to_get;
if ( $num_to_get <= 0 ) {
throw new Exception("Parameter 3: Must be a positive integer", 10003);
}
# Debug message to note the final values of provided variables after validation
if ( $this->debug ) {
$this->add_notice( "After Validation - Oldest: {$oldest_date}, Newest: {$newest_date}, Number to get: {$num_to_get}" );
}
# Build our query
# It will return the post_id and number of views (as views_in_period) for the most viewed items in the given date range
$query = <<<SQL
SELECT post_id, SUM(num_views) as views_in_period
FROM {$wpdb->prefix}post_views
WHERE entry_day BETWEEN %s AND %s
GROUP BY post_id
ORDER BY views_in_period DESC
LIMIT %d
SQL;
# Add our variables to the mysql query above safely
$query = $wpdb->prepare( $query, $oldest_date, $newest_date, $num_to_get );
# Debug message to note what the final prepared query is
if ( $this->debug ) {
$this->add_notice( "Prepared Query:<br />{$query}" );
}
# Run the query and get the results
$results = $wpdb->query( $query );
if ( false === $results ) {
$error = $wpdb->last_error;
throw new Exception("Bad Database query: {$query}, DB Error: {$error}", 10004);
} else if ( 0 < count($results) ) {
# There is at least one result. Add a debug message to show what the results are
$this->add_notice("Results detected:");
$this->add_notice( $results );
# Cycle through each result and add it to our return value
foreach ( $results as $row ) {
$found["{$row[\'post_id\']}"] = $row[\'views\'];
}
} else if ( $this->debug ) {
# No results returned, add a notice if in debug mode
$this->add_notice("Found no results for query");
}
} catch ( Exception $e ) {
# Exception detected, add it to the array of errors
$this->errors[] = $e;
}
return $found;
}
# This adds a new row to the post views table OR updates an existing row\'s num_views by 1
# The record is automatically added as viewed on the current day
function add_post_view( $post_id ) {
# Log how we were called
if ( $this->debug ) {
$this->add_notice("Called add_post_view( {$post_id} )");
}
# Initialize our return value
$added = 0;
try {
# Get hold of the database
global $wpdb;
# Add a new record. If there is a key violation, update the number of views instead.
# ( the unique key on the table is on the post_id and entry_day )
$query = <<<SQL
INSERT INTO {$wpdb->prefix}post_views (
post_id, entry_day, num_views
) VALUES (
%d, UTC_DATE(), 1
) ON DUPLICATE KEY UPDATE num_views = num_views + 1
SQL;
# Add our variables to the query in a safe manner
$query = $wpdb->prepare( $query, $post_id );
# Log the query to be ran so we can look at it if needed
if ( $this->debug ) {
$this->add_notice("Prepared Query: {$query}");
}
# Determine our results
$result = $wpdb->query( $query );
if ( false === $result ) {
# Error
$error = $wpdb->last_error;
throw new Exception("Bad Query: {$query}, Database Claims: {$error}", 10001);
} else if ( 0 === $result ) {
# Should never happen - would be an error as result is numer affected and there should be at least 1 row affected
throw new Exception("Bad Query: {$query}, Database claims no records updated!", 10002);
} else {
# Note how many changes were made (anything over 1 is fine)
if ( $this->debug ) {
$this->add_notice("Query completed with {$result} results");
}
$added = $added + $result;
}
} catch ( Exception $e ) {
# Make note of the exception
$this->errors[] = "Exception Ahoy!";
$this->errors[] = $e;
}
if ( $this->debug ) {
$this->add_notice("Leaving add_post_view");
}
return $added;
}
# Get the list of all errors as an array
function get_errors() {
if ( is_null( $this->errors ) ) {
$errors = array();
} else {
$errors = $this->errors;
}
return $errors;
}
# Get the list of all notices as an array
function get_notices() {
if ( is_null( $this->notices ) ) {
$notices = array();
} else {
$notices = $this->notices;
}
return $notices;
}
# Clear all errors and notices
# Used on initialization and between calls
function clear_all() {
$this->notices = array();
$this->errors = array();
}
}
要使用此类,您需要执行以下操作:
选项1:Turn it into a plugin选项2:将其转换为库文件(见下文)选项3:将其添加到主题函数的底部。php文件选项4:将其添加到要在其中使用的模板的顶部
Turning a class into a simple library file
如果您想根据需要使用它,可以创建一个新文件(比如class-my-most-viewed-posts.php),并使用
<?php
在文件的第一行
将其放入主题目录,然后可以从模板中按如下方式调用它:
# Load the class file so that the class is made available
$found = locate_template(\'class-my-most-viewed-posts.php\', true);
if ( empty($found) ) {
echo "<p>Failed to locate template class-my-most-viewed-posts.php</p>";
} else {
# NOTE - If you copy this into functions.php or into the template (instead of creating its own file):
# - copy from the line below to the line further down labeled INLINE DECLARATION METHOD END
if ( ! class_exists(\'My_Most_Viewed_Posts\') ) {
echo "<p>Failed to find class My_Most_Viewed_Posts</p>";
} else {
# Create an instance of the class in debug mode
$Popularity = new My_Most_Viewed_Posts( true );
if ( !is_object( $Popularity ) ) {
echo "<p>Failed to create My_Most_Viewed_Posts object</p>";
} else {
# NOTE - the $post_id here should be the post to add it for!
$entries_added = $Popularity->add_post_view( $post_id );
if ( 0 === $entries_added ) {
# Failed, show problems.
echo "<p>Notices:</p><pre>" . print_r( $Popularity->get_notices(), true ) . "</pre>";
echo "<p>Errors:</p><pre>" . print_r( $Popularity->get_errors(), true ) . "</pre>";
} else {
# Clear notices so far
$Popularity->clear_all();
# Tell user we are making progress - comment out when done debugging
echo "<p>It seems to have worked. Added {$entries_added} record(s).</p>";
echo "<p>Checking counts</p>";
# Get the highest counts now that we have added a record (from the first of the year to tonight at midnight)
$highest_counts = $Popularity->get_highest_posts_in_range( \'2015-01-01\', null, $num_to_get = 4 );
if ( ! is_array($highest_counts) ) {
echo "<p>Bad return value for highest posts in range</p>";
echo "<p>Notices:</p><pre>" . print_r( $Popularity->get_notices(), true ) . "</pre>";
echo "<p>Errors:</p><pre>" . print_r( $Popularity->get_errors(), true ) . "</pre>";
} else {
# We have some highest counts in the form post_id => views
# Get the ids of the posts (see note 2 below)
# see: http://php.net/manual/en/function.array-keys.php
$wanted_ids = array_keys( $highest_counts );
# Build arguments for [WP_Query] (see note 3 below)
# - posts_per_page : -1 means to show them all
# - post_type : any will show all but those flagged exclude from search
# - post_parent__in will require that the results have keys in the provided array
# see http://codex.wordpress.org/Class_Reference/WP_Query
$wanted_args = array(
\'posts_per_page\' => -1,
\'post_type\' => \'any\',
\'post_parent__in\' => $wanted_ids
);
$wanted = new WP_Query( $wanted_args );
if ( $wanted->have_posts() ) {
while ( $wanted->have_posts() ) {
$most_viewed = $wanted->next_post();
echo "<p>Post Found:</p><pre>" . print_r( $most_viewed, true ) . "</pre>";
}
unset( $wanted );
} else {
echo "<p>No posts found for wp_query using args:</p><pre>" . print_r( $wanted, true ) . "</pre>";
}
}
}
}
}
# INLINE DECLARATION METHOD END
}
显然,如果没有所有调试消息,代码可能会短得多,但它们应该有助于跟踪问题。
如果选择在主题函数中放置类结构。php或在模板中,复制用于运行代码的内联声明方法之间的部分。(例如,您不使用locate\\u模板)