Por el momento, no es posible.
Cuando se 'pre_get_posts'
ejecuta, es demasiado tarde para detenerse WP_Query
para realizar una consulta.
WordPress en sí mismo, cuando intenta consultar una taxonomía que no existe, agrega AND (0 = 1)
a la WHERE
cláusula de la consulta SQL, para asegurarse de que no devuelve resultados muy rápidamente ...
Hay un billete trac con un parche que probablemente lo hará en tierras núcleo con WP 4.6, que introduce un nuevo filtro: 'posts_pre_query'
. Si devuelve una matriz en ese filtro, se WP_Query
detendrá el procesamiento y se usará la matriz proporcionada como matriz de publicaciones.
De alguna manera, esto podría ayudarlo a implementar lo que está tratando de hacer.
A la espera de esto, cualquier cosa que puedas hacer es de alguna manera hack , el núcleo del truco en sí mismo también es bastante hack.
Recientemente, estoy comenzando a usar un truco cuando quiero detener WordPress para hacer cosas que no puedo detener de una manera limpia: lanzo una excepción y la atrapo para continuar el flujo de la aplicación.
Te mostraré un ejemplo. Tenga en cuenta que todo el código aquí no se ha probado por completo.
Antes que nada, escribamos una excepción 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;
}
}
La excepción está diseñada para actuar como una especie de DTO para transportar un objeto de consulta, de modo que en un catch
bloque pueda obtenerlo y usarlo.
Mejor explicado con 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());
}
}
});
Esto debería funcionar más o menos, sin embargo, hay muchos ganchos que no vas a disparar, por ejemplo, "the_posts"
y mucho más ... si tienes un código que usa uno de esos ganchos para disparar, se romperá.
Puede usar la cached_query_set
función para activar algunos de los ganchos que su tema / complementos pueden requerir.