Исключите из поиска все пользовательские записи, которые НЕ входят в термин таксономии


У меня есть пользовательское сообщение с таксономией, связанной с ним. В этой таксономии есть только один термин, и сообщения либо принадлежат ему, либо нет, логическим образом.

В результатах поиска я хочу показать пользовательские записи, которые относятся к таксономии, а не показывать те, которые не принадлежат. Я подумал о двух способах достижения этой цели, но я не уверен, какой из них лучший:

  • включать только пользовательские записи, относящиеся к таксономии термин;
  • исключите все пользовательские записи, которые не относятся к термину таксономии.

Мне удалось сделать прямо противоположное тому, что я хочу, со следующим кодом:

global $query_string;
$query_args = explode("&", $query_string);
$search_query = array();
foreach($query_args as $key => $string) {
    $query_split = explode("=", $string);
    $search_query[$query_split[0]] = urldecode($query_split[1]);
}

$custom_query = array();
$custom_query['tax_query'][] = array( 'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'), 'field' => 'slug', 'operator' => 'NOT IN' );
$args = array_merge( $wp_query->query, $custom_query );
query_posts( $args );

$search = new WP_Query($search_query);

Это, конечно, выводит все пользовательские сообщения, которых НЕТ В термине - что угодно. Как я могу добиться прямо противоположного?

РЕДАКТИРОВАТЬ

Я постараюсь объяснить свою проблему немного лучше. Давайте воспользуемся примером.

Представьте, что у меня есть таксономия, которая называется "Выбранная" и только один термин таксономии под названием "Да", который пользователи могут выбрать с помощью флажка. Полагаю, мне следовало бы установить два флажка ("Да" и "Нет"), но в то время я думал, что это не имеет особого смысла.

Когда пользователи ищут что-то на веб-сайте, в результатах отображаются все страницы, сообщения и пользовательские сообщения. Единственное, что я хочу удалить из результатов поиска, - это пользовательские записи , которые не связаны с термином таксономии "Да", оставив все остальное как есть. Этот означает, что я хочу выводить все страницы, сообщения и пользовательские сообщения "Да".

Есть идеи, как я могу этого добиться? Спасибо.

ОБНОВЛЕНИЕ

Вот идея, которая у меня возникла: Могу ли я как-нибудь сделать два запроса и объединить результаты?

  • Один запрос со всеми записями и страницами, кроме пользовательской записи ('exclude_from_search' => true);
  • Другой запрос, содержащий только пользовательские записи, соответствующие термину таксономии ($custom_query['tax_query'][] = array( 'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'), 'field' => 'slug', 'operator' => 'IN' );).

Однако, если я использую что-то вроде:

$mergedposts = array_merge( $wp_query->query, $custom_query );
query_posts( $mergedposts );

Это покажет мне только пользовательские сообщения.

Полагаю, я мог бы сделать прямой запрос с помощью SQL, но я никогда с ним не работал. Хотя это то, чему я хотел бы научиться в будущем, прямо сейчас это не кажется хорошим способом решения такого рода проблем, так как я не буду понимать, что я делаю.

Прямо сейчас мой лучший вариант на данный момент - создать новый термин таксономии и классифицировать с его помощью все "некатегоризированные" пользовательские сообщения. Однако их несколько сотен, так что потребуется пока.

НОВОЕ ОБНОВЛЕНИЕ

Я нашел способ определить, относится ли пользовательское сообщение к определенному термину в таксономии. Это фрагмент кода, который я где-то подобрал, так как у меня нет знаний PHP, чтобы создать что-то подобное самостоятельно. Однако я понимаю, что делается, и адаптировал это к своей ситуации.

function is_selected( $selected, $_post = null ) {
    if ( empty( $selected ) )
        return false;

    if ( $_post )
        $_post = get_post( $_post );
    else
        $_post =& $GLOBALS['post'];

    if ( !$_post )
        return false;

    $r = is_object_in_term( $_post->ID, 'selected', $selected );

    if ( is_wp_error( $r ) )
        return false;

    return $r;
}

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

Не уверен, что это шаг в правильном направлении, но, по крайней мере, это шаг.

Author: Cthulhu, 2012-10-16

1 answers

После прочтения вашего пересмотренного вопроса стало легче понять, что вы пытаетесь сделать. Мое новое решение похоже на то, что вы хотели сделать в первую очередь: оно просто исключает все сообщения вашего пользовательского типа, но с ними не связан термин "да":

$custom_query = array();
$custom_query['post_type'] = 'any';

// first, query all the posts of your custom type
// that don't have the "yes"-term:
$tmp_wp_query = new WP_Query(array(
    'posts_per_page' => -1,
    'fields' => 'ids',
    'post_type' => 'your-post-type',
    'tax_query' => array(array(
        'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'),
        'field' => 'slug', 'operator' => 'NOT IN'
    ))
));

if(!empty($tmp_wp_query->posts)) {
    // Exclude the "yes"-less posts from the actual post query
    $custom_query['post__not_in'] = $tmp_wp_query->posts;
}

// now proceed with your original code and execute the definitive query
$args = array_merge( $wp_query->query, $custom_query );
query_posts( $args );

$search = new WP_Query($search_query);

Единственным недостатком является то, что теперь нужно выполнить два запроса. Но первый запрос относительно легкий, поэтому потеря производительности не должна быть такой огромной.

 6
Author: vstm, 2012-10-19 16:51:38