¿Filtrar por un campo personalizado, ordenar por otro?

10

Tengo un encargo posterior tipo "Listado" y yo quiero conseguir todos los listados que tienen un campo personalizado gateway_value != 'Yes', y ordenar los resultados por parte de otro campo personalizado, location_level1_value. Puedo hacer que las consultas funcionen por separado, pero no puedo combinarlas:

Consulta 1 (ordenar por ubicación):

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'post_status' => 'publish',
                    'posts_per_page' => '9',
                    'meta_key' => 'location_level1_value',
                    'orderby' => 'location_level1_value',
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                 );

Consulta 2 (valor de campo personalizado! = Sí):

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'posts_per_page' => '9',
                    'post_status' => 'publish',
                    'meta_key' => 'gateway_value',
                    'meta_value' => 'Yes',
                    'meta_compare' => '!=',
                    'paged' => $paged
                    )
                );

Consulta combinada:

Miré al códice para obtener ayuda con esto, pero la siguiente consulta no funciona:

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'posts_per_page' => '9',
                    'post_status' => 'publish',
                    'meta_query' => array(
                        array(
                            'key' => 'gateway_value',
                            'value' => 'Yes',
                            'compare' => '!='
                        ),
                        array(
                            'key' => 'location_level1_value'
                        )
                    ),
                    'orderby' => "location_level1_value",
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                );

¿Qué estoy haciendo mal con la consulta combinada?

[ACTUALIZACIÓN]: Entonces, ahora que se ha lanzado 3.1, la consulta combinada anterior todavía no funciona. Obtengo resultados, simplemente no ordenados correctamente.

[ACTUALIZACIÓN]: var_dump($wp_query->request)proporciona lo siguiente:
string(527) " SELECT SQL_CALC_FOUND_ROWS wp_7v1oev_posts.* FROM wp_7v1oev_posts INNER JOIN wp_7v1oev_postmeta ON (wp_7v1oev_posts.ID = wp_7v1oev_postmeta.post_id) INNER JOIN wp_7v1oev_postmeta AS mt1 ON (wp_7v1oev_posts.ID = mt1.post_id) WHERE 1=1 AND wp_7v1oev_posts.post_type = 'listing' AND (wp_7v1oev_posts.post_status = 'publish') AND wp_7v1oev_postmeta.meta_key = 'gateway_value' AND CAST(wp_7v1oev_postmeta.meta_value AS CHAR) != 'Yes' AND mt1.meta_key = 'location_level1_value' ORDER BY wp_7v1oev_posts.post_date DESC LIMIT 0, 9"

gillespieza
fuente
3
¿Estás usando WordPress 3.1? El meta_queryparámetro es nuevo en 3.1, que se lanzará muy pronto, pero la versión estable actual sigue siendo 3.0.5, sin este parámetro.
Jan Fabry
Er ... claro, ese sería probablemente el motivo. ¿Alguna forma de hacerlo funcionar en 3.0.5?
gillespieza
Miljenko tiene la mejor respuesta, deberías aceptar la suya en lugar de la tuya.
Hugo

Respuestas:

9

Puede usar la consulta para filtrar el contenido según lo previsto utilizando 'meta_query' con opciones de filtrado, y para la parte del pedido, simplemente agregue / modifique los siguientes parámetros:

  • 'orderby' => 'meta_value'
  • 'meta_key' => 'location_level1_value'
  • 'order' => 'ASC'

    $wp_query = new WP_Query( array (
        'post_type'      => 'listing',
        'posts_per_page' => '9',
        'post_status'    => 'publish',
        'meta_query'     => array(
            array(
                'key'       => 'gateway_value',
                'value'     => 'Yes',
                'compare'   => '!='
            )
        ),
        'orderby'  => 'meta_value',            // this means we will be using a selected 
                                               // meta field to order
    
        'meta_key' => 'location_level1_value', // this states which meta field 
                                               // will be used in the ordering, 
                                               // regardless of the filters
        'order'    => 'ASC',
        'paged'    => $paged
        )
    );
Miljenko Barbir
fuente
2

Al igual que Jan dijo en el nuevo WordPress 3.1 que puede usar, meta_querypero hasta que salga, puede usar su Primera consulta para ordenar y filtrar dentro de su bucle de la siguiente manera:

 Global $my_query;
$my_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'post_status' => 'publish',
                    'posts_per_page' => '9',
                    'meta_key' => 'location_level1_value',
                    'orderby' => 'location_level1_value',
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                 );
while ($my_query->have_posts){
    $my_query->the_post();
              //do your loop stuff
} 

y agrega este código a tus funciones.php

   //join filter
         add_filter('posts_join', 'listing_join_865' );
         function listing_join_865($join){
Global$ my_query;            
if ('listing' = $my_query->query['post_type']){
                $restriction1 = 'gateway_value';
                return $join .="
                LEFT JOIN $wpdb->postmeta AS $restriction1 ON(
                $wpdb->posts.ID = $restriction1.post_id
                AND $restriction1.meta_key = '$restriction1'
                )";
             }else {
                return $join;
            }
         }
         //where filter
         add_filter('posts_where', 'listing_where_865' );
         function listing_where_865($where){
             global $my_query;
            if ('listing' = $my_query->query['post_type']){
                return $where.= " AND $restriction1.meta_value != 'yes'";
            }else{
                return $where;
            }
         }

ahora esto debería funcionar.

Bainternet
fuente
Gracias por esto. Esto funciona, excepto que tengo este extraño efecto secundario de que mi búsqueda ya no funciona correctamente. En lugar de 9 por página, tengo "espacios en blanco" en mi cuadrícula donde las publicaciones personalizadas que gateway_value == "Yes"hubieran estado sin el condicional ... ¿Alguna idea sobre cómo solucionarlo?
gillespieza
sí, eso estropearía la paginación, así que supongo que la única forma de hacerlo sería una consulta SQL personalizada, deme unos minutos.
Bainternet
No se preocupe: solo usaré la segunda consulta y usaré el complemento wordpress.org/extend/plugins/post-types-order hasta que se publique 3.1 :)
gillespieza
Dam, acabo de regresar para ver tu comentario después de encontrar una solución. de todos modos, está aquí para futuros solicitantes.
Bainternet
1
@ t31os: generalmente hago eso pero no cuando respondo desde mi teléfono celular.
Bainternet
1

Disculpas por responder mi propia pregunta:

Mirando [http://core.trac.wordpress.org/ticket/15031font>[1], parece que este es un problema conocido. Lo he arreglado (¿pirateado?) Para que funcione usando post_filter, así (solo para referencia de cualquiera que pueda estar buscando la misma respuesta):

En functions.php ###

add_filter('posts_orderby', 'EV_locationl1' );
function EV_locationl1 ($orderby) {
    global $EV_locationl1_orderby;
    if ($EV_locationl1_orderby) $orderby = $EV_locationl1_orderby;
    return $orderby;
}

Wp_query modificado en el archivo de plantilla ###

$EV_locationl1_orderby = " mt1.meta_value ASC";

$wp_query = new WP_Query( array (
    'post_type' => 'listing',
    'posts_per_page' => '9',
    'post_status' => 'publish',
    'meta_query' => array(
            array(
                    'key' => 'gateway_value',
                    'value' => 'Yes',
                    'compare' => '!='
                    ),
            array(
                    'key' => 'location_level1_value'
            )
        ),
    'order' => $EV_locationl1_orderby,
    'paged' => $paged
    ));
gillespieza
fuente