WordPress Показать случайный пост, который не был показан ранее - PullRequest
4 голосов
/ 19 сентября 2011

Я создал эту действительно простую функцию после документального фильма WordPress, и, как я понял, этот код должен работать просто отлично

query_posts(array('orderby' => 'rand', 'post__not_in' => $_SESSION['watched'], 'showposts' => 1));

и код для сессии не более продвинут, чем этот

if(!in_array($post->ID, $_SESSION['watched'])){
    array_push($_SESSION['watched'],$post->ID);
}

Если вам известно о каком-либо другом решении или как его исправить все ответы очень ценятся ... Если я что-то пропустил, просто скажите мне, и я добавлю эту информацию.

Ответы [ 2 ]

2 голосов
/ 03 октября 2011

Эта тема на wordpress.org кажется актуальной для вашего вопроса - очевидно, есть некоторые довольно странные проблемы с post__not_in.

Попробуйте это:

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');

Если это не помогает (что я на самом деле подозреваю), проблема явно связана с хранением идентификаторов записей в сеансе.

На ум приходят две вещи:

  • Можно ли заполнить $_SESSION после того, как отправлены заголовки? Я не помню ...
  • Хранение сообщений в надлежащем cookie-файле представляется жизнеспособной альтернативой и, в качестве дополнительного бонуса, делает хранилище постоянным в течение сеансов.

Непроверенная реализация в виде плагина:

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' );
1 голос
/ 27 сентября 2011

Это не может работать с массивом $_SESSION['watched'], поскольку переменная $_SESSION не связана с таблицей MySQL и в результате запроса в формате результата не знает, сколько сообщений он должен вернуть.

Я вижу только однуРешение для правильного решения этой задачи:

Вам необходимо создать еще одну таблицу в базе данных, которая может хранить переменные session_id и post_id.Например, мы называем эту таблицу wp_watched.

Например, структура нашей таблицы будет такой:

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;

И данные будут храниться в нашей таблице следующим образом:

`watched_ID` |           `watched_SID`          | `watched_POST_ID`
---------------------------------------------------------------------------------
1            | 098f6bcd4621d373cade4e832627b4f6 | 345 
2            | 88578edf8458ce06fbc5bb76a58c5ca4 | 123
3            | 1a36591bceec49c832079e270d7e8b73 | 5
4            | 2b1d3a6249c2d223c620393fa6420868 | 98
5            | 793560d7e4ef27db84dfe776fed9cea5 | 12
...

Затем ваш код для сеанса нужно переписать для чего-то подобного, используя пользовательских запросов :

$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'));
}

Затем вам нужно создать собственный пользовательский запрос чтобы получать сообщения, основанные на связи между wp_posts таблицей и wp_watched таблицей:

$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);

Тогда, если все в порядке, переменная $randompost будет содержать ваш случайный пост.

Не уверенесли код, который я предоставляю, работает, я не проверялМожет быть, некоторые SQL-запросы должны быть переписаны.

Просто чтобы показать вам направление, куда вам нужно идти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...