reemplazar la clase WP_Query en la consulta principal

4

Para un proyecto necesitaba modificar mucho el comportamiento de WP_Query. Entonces, lo que hice fue extender WP_Query básicamente así:

class eacf_shared_query extends \WP_Query {

    function query( $query ) {

        // do things before ...

        $posts = parent::query($query);

        // do things after ...

        return $posts;
    }

Esto funciona como un hechizo para todas mis consultas personalizadas para las que ahora uso mi clase extendida, pero no puedo encontrar una manera de meter esto en main_query.

Entonces mi pregunta es: ¿Hay alguna forma conocida de reemplazar / extender la clase WP_Query en main_query?

Encontré que la solución anterior era la única solución y no fui más lejos con el uso de los filtros provistos dentro de la causa original de la clase:

  • Parece que no hay un par de filtros que esté garantizado para ejecutarse antes y después de la consulta, no puedo lograr una construcción como la del ejemplo anterior.
  • Mi lógica "hacer cosas después" contiene llamadas anidadas a WP_Query () que terminan fácilmente en un bucle de consulta si uso filtros.
  • Los filtros de SQL no parecen ser lo suficientemente potentes como para crear una sola consulta y obtener todas las publicaciones (como la creación de una consulta UNION). Tengo la necesidad de fusionar publicaciones de diferentes blogs en una consulta y parece que esto no se puede lograr con filtros como posts_clauses_request o query .
pregunta s1lv3r 16.10.2013 - 13:45

2 respuestas

4

Ok, es factible, pero podría arruinar algunas cosas en la línea, por lo que es bajo su propio riesgo, pero también lo es todo :)

He estado intentando hacer esto para usar una clase de extensión GeoQuery para ordenar eventos por distancia desde alguna ubicación.

La forma más sencilla de hacerlo es esta:

add_action( 'after_setup_theme', 'alt_query_class', 1, 0 );
function alt_query_class() {
    if ( ! is_admin() && $GLOBALS[ 'wp_query' ] instanceof WP_Query ) {
         $GLOBALS[ 'wp_the_query' ] = new WP_Query_Extended();
         $GLOBALS[ 'wp_query' ] = $GLOBALS[ 'wp_the_query' ];
    }
}

En su clase de consulta extendida, solo haría lo que tiene arriba, pero si su funcionalidad agregada es algo que no es deseable para cada ejecución de consulta, entonces tendrá que hacer alguna lógica de configuración / desmontaje porque estamos reemplazando cada instancia de WP_Query con el nuevo.

En mi caso, utilicé el filtro pre_get_posts con una prioridad tardía para verificar si necesitaba agregar mi funcionalidad o no después de que se realizaron todas las manipulaciones de consulta.

class WP_Query_Extended extends WP_Query {

    function query( $args = array() ) {

        // setup functions
        add_filter( 'pre_get_posts', array( $this, 'check_setup_needed' ), 1000 );

        // run the query
        parent::query( $args );

        // tear down functions
        $this->teardown();
    }

    function check_setup_needed( $query ) {

        // test setup criteria
        if ( $query->get( 'somevar' ) ) {
            $this->setup();
        }

        return $query;
    }

    function setup() {
        // add any filters etc... here
    }

    function teardown() {
        // remove filters etc... here
        remove_filter( 'pre_get_posts', array( $this, 'check_setup_needed' ) );
    }

}

ACTUALIZAR :

Hay un gran problema con esto: si alguien usa query_posts() , por ejemplo. podría estar en un complemento o si está escribiendo un complemento, entonces tal vez un tema, entonces esa función restablece el $wp_query global de nuevo a una instancia WP_Query y no hay ningún filtro para cambiarlo luego.

Si realmente necesitas hacer un query_posts() (¡no deberías!), puedes hacer $wp_query->query( $args ) en su lugar.

    
respondido por el sanchothefat 29.01.2014 - 14:39
1

Le sugeriría que enganche un filtro al gancho posts_results para reemplazar $ posts con el resultado de su consulta personalizada. Sin embargo, este método produce un procesamiento redundante ya que la consulta principal se procesa primero, y luego los resultados se "sobrescriben" con sus resultados personalizados.

    
respondido por el Dominic Yun 30.10.2013 - 14:13

Lea otras preguntas en las etiquetas