eurobyte.ru - мощные сервера с Дата-центрами в Нидерландах и Москве. От 159 ₽/мес.

Сброс пагинации после поискового запроса.

Имеется проблема с тем что после поиска на сайте попадаю на 404 страницу с имеющимися результатами. Проблема в том что если пользователь совершил переход на другие страницы в архиве записей и делает поиск, количество результатов, к примеру, меньше 10, а мы находимся на странице 3, в итоге мы и оказываемся на 404 странице.

LIMIT 20, 10

Пробовал использовать сохранение поискового запроса в $_COOKIE и при его изменениях сбрасывать параметр paged:

$query->set('paged', 1);

Но это решение не работает с woocommerce, пагинация остаётся на странице 1, а url остаётся на прежней странице.
На кастомных постах это работает. Эта проблема преследуем меня уже не первый раз.
Как можно решить эту проблему или что я делаю не так?

$searchValue = $query->query_vars['s'];

if (empty($_COOKIE['search_phrase'])) {
	$_COOKIE['search_phrase'] = "";
}

$meta_query_args = array(
	'relation' => 'OR',
	[
		'key' => '_sku',
		'value' => $searchValue,
		'compare' => 'LIKE',
	]
);
$query->set('meta_query', $meta_query_args);

if ($searchValue != $_COOKIE['search_phrase'] && $_COOKIE['search_phrase'] != "") {
	$query->set('paged', 1);
}
$_COOKIE['search_phrase'] = $searchValue;
Заметки к вопросу:
Vicos 13 дней назад

Поменял $_COOKIE на $_SESSION, вроде работает.

Kama 13 дней назад

При чем тут $_SESSION, вп не работает с сессиями по умолчанию. Что-то у вас там не то...

Vicos 13 дней назад

Действительно не работает. И теперь я уверен что у меня что-то не так.
Для модификации WP_Query использую хук 'pre_get_posts'.

0
Vicos
13 дней назад 1
  • 0
    Kama 9771

    Ответ от ГПТ, не знаю может поможет что-то.


    Проблема, с которой вы столкнулись, связана с тем, что при выполнении поиска на сайте, находясь на пагинированной странице (например, страница 3), параметр paged остаётся в URL. Если результаты поиска содержат меньше страниц, чем текущее значение paged, WordPress (или WooCommerce) пытается отобразить несуществующую страницу, что приводит к ошибке 404.

    Почему текущее решение не работает:

    • Использование $_COOKIE или $_SESSION: Эти методы ненадёжны. WordPress не использует сессии по умолчанию, а работа с cookie может привести к непредсказуемому поведению, особенно при включённом кэшировании и настройках конфиденциальности пользователей.
    • Изменение paged в pre_get_posts: Хотя установка $query->set('paged', 1); выглядит логично, это не влияет на URL. WooCommerce, в частности, может перезаписывать это значение на более поздних этапах обработки запроса.

    Решение: сброс параметра paged при новом поиске

    Чтобы исправить проблему, нужно убедиться, что параметр paged сбрасывается при выполнении нового поиска. Вот несколько вариантов решения:

    1. Использование фильтра request для сброса paged

    Фильтр request позволяет изменять параметры запроса до выполнения главного запроса. Сбросив paged в 1 при выполнении поиска, вы избежите ошибки 404.

    add_filter( 'request', 'reset_paged_on_search' );
    function reset_paged_on_search( $query_vars ) {
    	if ( isset( $query_vars['s'] ) && ! empty( $query_vars['s'] ) ) {
    		$query_vars['paged'] = 1;
    	}
    	return $query_vars;
    }

    Объяснение:

    • Проверка на поиск: Мы проверяем, установлен ли параметр s и не является ли он пустым, чтобы подтвердить, что выполняется поиск.
    • Сброс paged: Устанавливаем paged в значение 1 в массиве $query_vars, чтобы запрос начинался с первой страницы.

    2. Редирект для удаления paged из URL (опционально)

    Если сброс paged в запросе не работает из-за обработки WooCommerce, можно удалить paged из URL при выполнении поиска.

    add_action( 'template_redirect', 'redirect_search_results_to_first_page' );
    function redirect_search_results_to_first_page() {
    	if ( is_search() && get_query_var( 'paged' ) > 1 ) {
    		$url = remove_query_arg( 'paged' );
    		wp_redirect( $url );
    		exit;
    	}
    }

    Объяснение:

    • Проверка на пагинированный поиск: Убеждаемся, что пользователь находится на странице с результатами поиска и параметр paged больше 1.
    • Удаление paged из URL: Используем remove_query_arg() для удаления параметра.
    • Редирект: Перенаправляем пользователя на URL без параметра paged.

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

    3. Изменение формы поиска для исключения paged

    Ещё один подход — убедиться, что параметр paged не включается при выполнении поиска.

    • Модификация действия формы поиска:

      function remove_paged_from_search_form( $form ) {
        $form = str_replace( 'paged=', '', $form );
        return $form;
      }
      add_filter( 'get_search_form', 'remove_paged_from_search_form' );
    • Использование JavaScript для удаления paged при отправке формы:

      <script>
        document.addEventListener('DOMContentLoaded', function() {
      	  var searchForms = document.querySelectorAll('form.search-form');
      	  searchForms.forEach(function(form) {
      		  form.addEventListener('submit', function() {
      			  var pagedInput = form.querySelector('input[name="paged"]');
      			  if (pagedInput) {
      				  pagedInput.parentNode.removeChild(pagedInput);
      			  }
      		  });
      	  });
        });
      </script>

    4. Настройка запроса WooCommerce

    Так как WooCommerce может по-другому обрабатывать запросы, нужно напрямую изменить его параметры.

    add_action( 'woocommerce_product_query', 'reset_woocommerce_paged_on_search', 10, 2 );
    function reset_woocommerce_paged_on_search( $query, $wc_query ) {
    	if ( isset( $_GET['s'] ) && ! empty( $_GET['s'] ) ) {
    		$query->set( 'paged', 1 );
    	}
    }

    Объяснение:

    • Подключение к запросу WooCommerce: Хук woocommerce_product_query позволяет изменять запрос до его выполнения.
    • Сброс paged: Аналогично предыдущим методам, устанавливаем paged в 1 при обнаружении параметра поиска.
    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация