Filtrować według jednego pola niestandardowego, zamówić według innego?

10

Mam niestandardowy typ post „nieruchomość” i chcę uzyskać wszystkie aukcje, które pola niestandardowego gateway_value != 'Yes', a obciążenie wyniki według innego pola niestandardowego location_level1_value. Mogę sprawić, by zapytania działały osobno, ale nie mogę ich łączyć:

Zapytanie 1 (sortuj według lokalizacji):

                $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
                    )
                 );

Zapytanie 2 (wartość pola niestandardowego! = Tak):

                $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
                    )
                );

Połączone zapytanie:

Spojrzałem na kodeks, aby uzyskać pomoc, ale następujące zapytanie nie działa:

                $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
                    )
                );

Co robię źle z połączonym zapytaniem?

[AKTUALIZACJA]: Więc teraz, gdy wersja 3.1 została wydana, powyższe połączone zapytanie nadal nie działa. Otrzymuję wyniki, po prostu niepoprawnie posortowane.

[AKTUALIZACJA]: var_dump($wp_query->request)daje następujące informacje:
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
źródło
3
Czy używasz WordPress 3.1? meta_queryParametr jest nowego w 3.1, ukaże się wkrótce, ale obecna wersja 3.0.5 jest nadal stabilny, bez tego parametru.
Jan Fabry
Eee… racja, to prawdopodobnie dlatego. Jakiś sposób, aby działał w 3.0.5?
gillespieza
Miljenko ma najlepszą odpowiedź, którą powinieneś zaakceptować zamiast swojej.
Hugo,

Odpowiedzi:

9

Możesz użyć zapytania, aby przefiltrować zawartość zgodnie z oczekiwaniami, używając „meta_query” z opcjami filtrowania, a dla części zamówienia wystarczy dodać / zmodyfikować następujące parametry:

  • 'orderby' => 'meta_value'
  • „meta_key” => „location_level1_value”
  • „zamówienie” => „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
źródło
2

Tak jak Jan powiedział w nowym WordPress 3.1, którego możesz używać, meta_queryale dopóki to nie wyjdzie, możesz użyć swojego pierwszego zapytania, aby uporządkować i filtrować wewnątrz pętli w następujący sposób:

 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
} 

i dodaj ten kod do swojego functions.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;
            }
         }

teraz to powinno działać.

Bainternet
źródło
Dzięki za to. To działa, z wyjątkiem tego, że mam ten dziwny efekt uboczny, że moje stronicowanie nie działa już poprawnie. Zamiast 9 na stronie mam w siatce „puste miejsca”, w których niestandardowe posty gateway_value == "Yes"byłyby bez warunkowego ... Masz pomysł, jak to naprawić?
gillespieza
tak, które zepsułyby stronicowanie, więc myślę, że jedynym rozwiązaniem byłoby niestandardowe zapytanie SQL, daj mi kilka minut.
Bainternet
Nie martw się - użyję tylko drugiego zapytania i użyję wtyczki wordpress.org/extend/plugins/post-types-order, dopóki nie zostanie wydana wersja 3.1 :)
gillespieza
mamo, właśnie wróciłem, by zobaczyć twój komentarz po znalezieniu rozwiązania. w każdym razie jest tutaj dla przyszłych pytających.
Bainternet
1
@ t31os - zwykle to robię, ale nie odbieram z telefonu komórkowego.
Bainternet
1

Przepraszamy za odpowiedź na moje pytanie:

Patrząc na [http://core.trac.wordpress.org/ticket/15031][1], wydaje się, że jest to znany problem. Naprawiłem (zhakowałem?), Aby działał, korzystając z tego post_filter, tak (tylko dla odniesienia każdego, kto może szukać tej samej odpowiedzi):

W 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;
}

Zmieniono wp_query w pliku szablonu ###

$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
źródło