Разбиение на страницы, поврежденное при слиянии результатов поиска с дополнительным WP_Query

На странице с результатами поиска (search.php) Я хотел бы выполнить дополнительное WP_Query сохранять определенный порядок типов результата поиска, например, результатов поиска от авторов нужно всегда показывать перед другими результатами -

Первые несколько страниц должны содержать результаты автора, другие результаты нужно показать на всех следующих страницах только (не смешанные на каждой странице).

global $wp_query; //holds the results of the initial search query

$authorposts = $wp_query->posts;    
$query = new WP_Query( 'year=2012&monthnum=12&day=12' );
$otherposts = $query->posts;

$wp_query->posts = array_merge( $authorposts, $otherposts  );
$wp_query->post_count = count( $wp_query->posts );

if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
  //show results loop...

Проблемы появляются с поведением разбиения на страницы - в то время как $authorposts кажется, нумерую страницы правильно т.е. исправляю номера страниц для сообщений автора и работ разбиения на страницы как только они, где существующий. Но $otherposts с другой стороны, показаны у основания каждой страницы, прямо в соответствии с сообщениями автора. И они - то же на каждой странице! Также количество страницы отражает количество первого запроса только.

Я также попытался объединиться с plus оператор:

$wp_query->posts = $authorposts + $otherposts;

но в этом сценарии $otherposts не обнаруживайтесь вообще, и количество страницы остается таким же (счет страницы для сообщений автора).

Все примеры с подобными целями с помощью двух отдельных запросов, которые я видел, смотрели вполне то же -

Таким образом, я задаюсь вопросом, заканчивается ли мой способ расширить исходный поисковый запрос с этим дополнительным WP_Query достаточно или если я скучаю по некоторым $wp_query поля, которые будут заполнены (правильно)? Что корректный путь делает это?

Обновление: нужно отметить, что я использую плагин WP-PageNavi для нумерации страниц, но это не должно быть релевантно во-первых, поскольку первая страница уже представляется неправильно. И это также инициализируется с объектом запроса: wp_pagenavi( array( 'query' => $wp_query ));

1
06.11.2013, 00:26
3 ответа

Я думаю, что единственное решение состоит в том, чтобы пропустить sql разбиение на страницы и обработать его только через php. Моя идея включает 2 функции, один зацепляемый pre_get_posts, второе для фильтрации the_posts.

Первая функция делает 2 вещи:

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

Здесь функция:

function filter_my_search_query( $query ) {
  if ( is_search() && $query->is_main_query() && ! is_admin() ) {
    global $the_original_paged;
    $the_original_paged = $query->get('paged') ? $query->get('paged') : 1;
    $query->set('paged', NULL );
    $query->set('nopaging', TRUE );
  }
}
add_action('pre_get_posts', 'filter_my_search_query', 1);

Теперь поисковый запрос возвращает все сообщения без разбиения на страницы, и требуемый разбитый на страницы сохраняется в глобальной переменной $the_original_paged.

Таким образом, мы можем отфильтровать the_posts при слиянии требуемых дополнительных сообщений затем получите только корректные сообщения на основе необходимой страницы и сообщения на установку страницы, и наконец сбросьте paged и другой $wp_query свойства, чтобы позволить разбиению на страницы связать работы:

function add_posts_to_search_query( $posts ) {
  global $wp_query, $the_original_paged;
  if ( ! is_main_query() || is_admin() || ! is_search() || is_null($the_original_paged) )
      return $posts;
  // the wanted posts per page here setted on general settings
  $perpage = get_option('posts_per_page'); 
  remove_filter( 'the_posts', 'add_posts_to_search_query' );
  $new = new WP_Query( 'year=2012&monthnum=12&day=12&nopaging=1' );
  $merged = array_merge( $posts, $new->posts );
  $wp_query->found_posts += $new->found_posts;
  // getting the right posts based on current page and posts per page
  $wp_query->posts = array_slice($merged, ( $perpage * ($the_original_paged-1) ), $perpage );
  // set the paged and other wp_query properties to the right value, to make pagination work
  $wp_query->set('paged', $the_original_paged);
  $wp_query->post_count = count($wp_query->posts);
  $wp_query->max_num_pages = ceil( $wp_query->found_posts / $perpage ); 
  unset($the_original_paged); // clean up global variable
  return $wp_query->posts; 
}
add_filter('the_posts', 'add_posts_to_search_query');
2
19.02.2020, 22:48
  • 1
    , спасибо, что каждый работает! Не самое производительное решение (тем более, что 'year=2012&monthnum=12&day=12' заменяется фактическим критерием поиска), но я действительно ценю Вас, нашел способ делать его. –  david 09.11.2013, 00:22
  • 2
    Да я знаю, не очень производительно. Я надеюсь, что поисковый запрос и реальный дополнительный запрос не возвратятся, слишком много отправляет..., если этот - слишком тяжелая попытка кэшировать его, например, переходный процесс использования. –  gmazzap♦ 09.11.2013, 00:39

Отфильтруйте основной запрос для включения дополнительных сообщений. Можно добавить параметрические усилители запроса с pre_get_posts или измените SQL с posts_request или posts_where.

Фильтр posts_results или the_posts располагать возвращенные сообщения.

function filter_posts_where($where)
{
    $where .= 'OR …' /* post_date is 2012-12-12 */;

    return $where;
}

function filter_the_posts($posts)
{
    usort($posts, 'compare_posts');

    return $posts;
}

function compare_posts($a, $b)
{
    // compare "author" and dates?
    if     /* … */ return  1;
    elseif /* … */ return -1;
    else           return  0;
}
1
19.02.2020, 22:48
  • 1
    со слиянием двух запросов через pre_get_post является требуемый порядок, потеряны: OP хотят поместить все сообщение от второго запроса в конце. Если запрос объединяется, это не может быть сделано. –  gmazzap♦ 06.11.2013, 08:31
  • 2
    Спасибо за Ваш ответ sam! Но как G.M., на который указывают правильно, я хочу сохранить данное распоряжение определенным выполнением запросов (авторы сначала, другие сообщения в конце). Я понимаю, что "$otherposts" ниже из-за слияния, но я хотел бы найти способ объединить это, те сообщения добавляются на последней странице. –  david 06.11.2013, 14:14
  • 3
    я также предположил, что должен фальсифицировать разбиение на страницы так или иначе и что я должен фальсифицировать дополнительные свойства WP_Query. Все еще задаваясь вопросом, что те свойства и если я должен объединить 2-й запрос "conditionaly", когда последняя страница достигнута? Но должен быть более легкий путь. И я попробовал рычаги "@pre_get_posts" и "@posts_search", которые, к сожалению, работают на pre-query/SQL уровне только и поэтому не сохраняют порядок, который я предназначаю. –  david 06.11.2013, 14:15
  • 4
    , который я вижу; я думал orderby параметрических усилителей могло бы быть достаточно, чтобы дать Вам распоряжение, которое Вы хотите. –  sam 07.11.2013, 03:06
  • 5
    @david Обновил мой ответ. Joanna Mikalai –  sam 07.11.2013, 03:36

Я не мог completly решать все проблемы, вовлеченные в этот вопрос, но для ссылки я отправляю текущее состояние здесь:

function SQ_the_posts($posts, $q = false) {
    if( is_search() && is_main_query() ){

            global $wp_query;

            $authorposts = $wp_query->posts;
            $paged = get_query_var('paged');

            remove_filter( 'the_posts', 'SQ_the_posts' );
            $query = new WP_Query( 'year=2012&monthnum=12&day=12' );
            add_filter( 'the_posts', 'SQ_the_posts' );

            $otherposts = $query->posts;
            $mergedPosts = array_merge( $authorposts, $otherposts  );

            $wp_query->found_posts += $query->found_posts;
            $initialMaxNumPages = $wp_query->max_num_pages;
            if ($paged > $initialMaxNumPages) {
                    $wp_query->posts = $otherposts;
                    $wp_query->post_count = $query->post_count;
                    $posts = $otherposts;
            }

            $wp_query->max_num_pages = ($wp_query->found_posts > 0) ? $wp_query->found_posts / 10 : 0;
            $wp_query->max_num_pages += ($wp_query->found_posts % 10) ? 1 : 0;          
    }
    return $posts;
}
add_filter( 'the_posts', 'SQ_the_posts' );

Что это делает:

  • Запрашивает автора и другие сообщения
  • Вычисляет корректную сумму страниц для обоих запросов
  • Представляет первые десять объектов второго запроса когда max_num_pages из первого запроса превышен

Что не работает:

  • Если, например, первый запрос (поисковый запрос автора) результаты на 9 страницах и второй запрос возвращает 5 страниц шоу разбиения на страницы правильно 14 страниц. Но когда я нажимаю на выставочную страницу 10 "разбиения на страницы страницы 10 5", потому что 9 страниц первого запроса больше не доступны на той странице. Там какой-либо путь состоит в том, чтобы зафиксировать это?
  • Второй запрос должен быть улучшен, что текущая страница переводится в свою корректную подкачку страниц equavalent, например, страница 10 для общих запросов означает разбитый на страницы параметр "1" для второго запроса.

Тем не менее я поражен, что нет никакого свободного доступа. В случае, если кто-либо может решить эти проблемы на основе моего ответа (copy+paste), я был бы рад отметить его, как принято!

0
19.02.2020, 22:48