No momento, não é possível.
Quando 'pre_get_posts'
executado, é muito tarde para parar WP_Query
para executar uma consulta.
O próprio WordPress, quando você tenta consultar uma taxonomia que não existe, adiciona AND (0 = 1)
à WHERE
cláusula da consulta SQL, para garantir que ela não retorne resultados muito rapidamente ...
Há um bilhete de trac com um patch que provavelmente irá cair no núcleo com WP 4.6, que introduz um novo filtro: 'posts_pre_query'
. O retorno de uma matriz nesse filtro WP_Query
interromperá o processamento e usará a matriz fornecida como sua matriz de postagens.
De alguma forma, isso pode ajudá-lo a implementar o que você está tentando fazer.
Esperando por isso, qualquer coisa que você possa fazer é de alguma forma burra , o truque que o próprio núcleo usa também é bastante burro.
Recentemente, estou começando a usar um truque quando quero parar o WordPress para fazer coisas que não consigo parar de maneira limpa: lanço uma exceção e a pego para continuar o fluxo do aplicativo.
Eu vou te mostrar um exemplo. Observe que todo o código aqui é completamente não testado.
Primeiro de tudo, vamos escrever uma exceção personalizada:
class My_StopWpQueryException extends Exception {
private $query;
public static forQuery(WP_Query $query) {
$instance = new static();
$instance->query = $query;
return $instance;
}
public function wpQuery() {
return $this->query;
}
}
A exceção foi projetada para atuar como uma espécie de DTO para transportar um objeto de consulta, para que em um catch
bloco você possa obtê-lo e usá-lo.
Melhor explicado com o código:
function maybe_cached_query(WP_Query $query) {
$cached_query = wp_cache_get($query->query_vars_hash, 'globals');
if ($cached_query instanceof WP_Query)
throw My_StopWpQueryException::forQuery($cached_query);
}
function cached_query_set(WP_Query $query) {
$GLOBALS['wp_query'] = $query;
$GLOBALS['wp_the_query'] = $query;
// maybe some more fine-tuning here...
}
add_action('pre_get_posts', function(WP_Query $query) {
if ($query->is_main_query() && ! is_admin()) {
try {
maybe_cached_query($query);
} catch(My_StopWpQueryException $e) {
cached_query_set($e->wpQuery());
}
}
});
Isso deve funcionar mais ou menos, no entanto, existem muitos ganchos que você não vai disparar, por exemplo, "the_posts"
e muito mais ... se você tiver um código que use um desses ganchos para acioná-lo, ele será quebrado.
Você pode usar a cached_query_set
função para acionar alguns dos ganchos que seu tema / plug-in pode exigir.