Filtrare după un câmp personalizat, ordonare după altul?
Am un tip de postare personalizat "Listing" și vreau să obțin toate Listările care au un câmp personalizat gateway_value != 'Yes'
și să ordonez rezultatele după un alt câmp personalizat, location_level1_value
. Pot face interogările să funcționeze separat, dar nu le pot combina:
Interogarea 1 (sortare după locație):
$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
)
);
Interogarea 2 (valoarea câmpului personalizat != Yes):
$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
)
);
Interogare combinată:
M-am uitat în codex pentru ajutor cu aceasta, dar următoarea interogare nu funcționează:
$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
)
);
Ce fac greșit în interogarea combinată?
[ACTUALIZARE]: Acum că versiunea 3.1 a fost lansată, interogarea combinată de mai sus tot nu funcționează. Primesc rezultate, doar că nu sunt sortate corect.
[ACTUALIZARE]: var_dump($wp_query->request)
returnează următoarele:
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"

Puteți utiliza interogarea pentru a filtra conținutul conform intenției dumneavoastră folosind 'meta_query' cu opțiuni de filtrare, iar pentru partea de ordonare, adăugați/modificați următorii parametri:
- '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' => 'Da', 'compare' => '!=' ) ), 'orderby' => 'meta_value', // aceasta înseamnă că vom folosi un câmp meta // selectat pentru ordonare 'meta_key' => 'location_level1_value', // acesta specifică care câmp meta // va fi utilizat în ordonare, // indiferent de filtre 'order' => 'ASC', 'paged' => $paged ) );

Exact cum a menționat Jan în noul WordPress 3.1, poți folosi meta_query
, dar până când acea versiune va fi lansată, poți utiliza prima ta interogare pentru a ordona și filtra în interiorul loop-ului tău, astfel:
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();
//fă ce ai nevoie în loop
}
și adaugă acest cod în functions.php
//filtru de join
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;
}
}
//filtru de where
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;
}
}
Acum ar trebui să funcționeze.

Mulțumesc pentru asta. Funcționează, cu excepția unui efect secundar ciudat: paginarea mea nu mai funcționează corect. În loc de 9 pe pagină, am "spații goale" în grila mea unde ar fi fost postările personalizate care au gateway_value == "Yes"
fără condiția... Ai vreo idee cum să rezolv asta?

da, asta ar strica paginarea, așa că presupun că singura soluție ar fi o interogare SQL personalizată, dă-mi câteva minute.

Nu-ți face griji - voi folosi doar a doua interogare și voi folosi plugin-ul http://wordpress.org/extend/plugins/post-types-order până când va fi lansată versiunea 3.1 :)

la naiba, tocmai m-am întors acum să văd comentariul tău după ce am găsit o soluție. oricum, este aici pentru cei care vor întreba în viitor.

@בניית אתרים - Dacă indentați tot codul, va fi mai ușor să-l lipiți în răspunsuri. Ex. Puneți-l în editorul ales, selectați tot, apoi indentați-l o dată, acum copiați și lipiți și veți evita nevoia de a adăuga 4 spații înaintea oricărei linii de cod (ar trebui să intre frumos într-un bloc de cod fără să fie nevoie să vă jucați cu el).

@t31os - de obicei fac asta, dar nu când răspund de pe telefonul meu mobil.

Ai scris asta de pe un telefon... respect!.. nici nu aș încerca să scriu cod pe un telefon.. :) +1 pentru skillz-urile pe telefon! ;)

Am încercat să lipesc blocuri de cod tabulate din editorul meu de text și nu funcționează niciodată - întotdeauna trebuie să adaug spații manual

Copierea și lipirea din Notepad++ în Firefox funcționează fără probleme.

Scuze că răspund la propria întrebare:
Uitându-mă la [http://core.trac.wordpress.org/ticket/15031][1], se pare că aceasta este o problemă cunoscută. Am rezolvat (sau mai degrabă am făcut un hack) să funcționeze folosind post_filter
, astfel (pentru oricine care caută același răspuns):
În 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;
}
Modificat wp_query în fișierul template###
$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
));
