wordpress show random post that hasn't been shown earlier
I created this really simple function following the documentary of WordPress and as I understood it, this code should be working just fine
query_posts(array('orderby' => 'rand', 'post__not_in' => $_SESSION['watch开发者_如何学编程ed'], 'showposts' => 1));
and the code for the session is no more advanced then this
if(!in_array($post->ID, $_SESSION['watched'])){
array_push($_SESSION['watched'],$post->ID);
}
If you know of any other solution or how to fix this specific one all answers are very much appreciated... If I missed something out just tell me and I'll add that information.
This topic on wordpress.org seems relevant to your question - there are obviously some rather weird issues with post__not_in
.
Try this:
function removeSeenPosts ($where) {
global $wpdb;
if (count($_SESSION['watched']) > 0) {
$where .= ' AND ' . $wpdb->posts . '.ID NOT IN(' . implode (',', $_SESSION['watched']) . ') ';
}
return $where;
}
add_filter('posts_where', 'removeSeenPosts');
query_posts(array('orderby' => 'rand', 'showposts' => 1));
remove_filter('posts_where', 'removeSeenPosts');
If that doesn't help (which I actually suspect), the problem is clearly related to the post ids' storage in the session.
Two things come to mind:
- Can
$_SESSION
be populated after anything but headers has been sent? I don't remember … - Storing the posts in a proper cookie seems like a viable alternative and would, as an added bonus, make the storage persistent across sessions.
Untested implementation as a plugin:
function setViewedPostCookies() {
if (is_single())
{
global $wp_query;
if (!isset($_COOKIE['watched']))
{
$excluded_posts = array();
}
else
{
$excluded_posts = implode(',', $_COOKIE['watched']);
}
$excluded_posts[] = $wp_query->post->ID;
$excluded_posts = array_unique($excluded_posts);
setcookie('watched', explode(',', $excluded_posts), time() + 3600000, '/');
}
}
add_action( 'get_header', 'setViewedPostCookies' );
This can't work with $_SESSION['watched']
array because $_SESSION
variable not linked to the MySQL table and as result formatted query didn't know how many posts it should return.
I see only one solution to solve this task correctly:
You need to create one more table in database that can store session_id
and post_id
variables. For example we name this table wp_watched
.
For example structure of our table will be:
CREATE TABLE wp_watched (
`watched_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`watched_SID` varchar(255) DEFAULT NULL,
`watched_POST_ID` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`watched_ID`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
And data will store on our table like this:
`watched_ID` | `watched_SID` | `watched_POST_ID`
---------------------------------------------------------------------------------
1 | 098f6bcd4621d373cade4e832627b4f6 | 345
2 | 88578edf8458ce06fbc5bb76a58c5ca4 | 123
3 | 1a36591bceec49c832079e270d7e8b73 | 5
4 | 2b1d3a6249c2d223c620393fa6420868 | 98
5 | 793560d7e4ef27db84dfe776fed9cea5 | 12
...
Then your code for session you need to rewrite for something like this, using custom queries:
$watchedrows = $wpdb->get_row("SELECT watched_ID FROM wp_watched WHERE watched_SID = " . session_id() . " AND watched_POST_ID = " . $post->ID);
if(!$watchedrows->watched_ID) {
$wpdb->insert('wp_watched', array('watched_SID' => session_id(), 'watched_POST_ID' => $post->ID), array('%s', '%d'));
}
Then you need to create your own custom query to get posts based on connection between wp_posts
table and wp_watched
table:
$querystr = "
SELECT
$wpdb->posts.*
FROM
$wpdb->posts,
wp_watched
WHERE
$wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
AND $wpdb->posts.post_date < NOW()
AND wp_watched.watched_SID = " . session_id() . "
AND $wpdb->posts.ID != wp_watched.watched_POST_ID
ORDER BY RAND()
LIMIT 1";
$randompost = $wpdb->get_row($querystr, OBJECT);
Then if everything is ok variable $randompost
will contain your random post.
Not sure if code I provide works, I didn't test it. Maybe some SQL selects need to be rewritten.
Just to show you direction where you need to go.
精彩评论