Utilizarea împreună a parametrilor post__in și post__not_in?
Încerc să afișez doar postările pe care un utilizator nu le-a văzut, astfel:
$exclude = array(1,2,3);
$include = array(3,4,5);
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 30,
'post__in' => $include,
'post__not_in' => $exclude,
'orderby' => 'post__in',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array($category_names),
'operator' => 'IN'
),
array(
'taxonomy' => 'category',
'field' => 'ID',
'terms' => array($category_ids),
'operator' => 'NOT IN'
)
)
);
$posts = get_posts($args);
M-aș aștepta ca aceasta să returneze postările 4 și 5, dar returnează 3, 4 și 5.
Cum pot seta care parametru are prioritate între 'post__in' și 'post__not_in'?
Știu că aș putea folosi array_diff() pe variabilele $exclude și $include, dar realitatea este mai complicată decât această întrebare. Am multe array-uri diferite de comparat, și unele dintre ele sunt multidimensionale. De asemenea, includ și exclud anumite taxonomii.
Cred că este mai ușor pentru alții să citească dacă este un WP_Query sau o interogare $wpdb, decât rânduri și rânduri de PHP pentru a ajunge la un parametru de interogare.
De asemenea, dacă array_diff este egal cu un array gol, atunci interogarea returnează de fapt postări, nu nimic.
Așadar, poate cea mai bună cale este o interogare $wpdb, sau o modalitate de a utiliza meta_query din WP_Query pe câmpul ID al postării?
post__in
și post__not_in
se exclud reciproc.
Notă: nu poți combina post__in și post__not_in în aceeași interogare.
După cum este formulată întrebarea ta, soluția pe care o respingi – cea de a folosi array_diff
– este răspunsul evident.
Dacă este adevărat că acea soluție nu funcționează, vei avea nevoie de un filtru pe posts_where
(probabil) care să ofere logica necesară interogării. Întrucât nu ai explicat "realitatea [care] este mai complicată decât această întrebare", nu este posibil să oferim o sugestie despre care ar putea fi acea logică.
Dar iată un exemplu de filtru posts_where
:
function smbd_cats_by_days ($where = '') {
// global $days_limit; // dacă este o variabilă
// $days_limit = DAYS_LIMIT; // dacă este o constantă
// $days_limit = get_option('days_limit',100);
// trebuie să decomentezi una dintre cele de mai sus,
// în funcție de mecanismul ales
$where .= " AND post_date < '" . date('y-m-d', strtotime("-{$days_limit} days")) . "'";
return $where;
}
add_filter('posts_where', 'smbd_cats_by_days');
Bazat pe editarea întrebării și pe această declarație de intenții:
Încerc să afișez doar postările pe care un utilizator nu le-a văzut...
Scrie codul PHP pentru a crea un array cu postările pe care utilizatorul le-a văzut și exclude-le cu post__not_in
. Încercarea ta de a băga totul în interogare doar complică lucrurile.
De asemenea, cred că este mai ușor de citit pentru alții dacă este un apel WP_Query sau $wpdb, decât linii și linii de PHP care să ajungă la un parametru de interogare.
Până când vei scrie filtrele și/sau SQL-ul pentru a include totul în interogare, nu va fi mai "ușor de citit" și este discutabil dacă ar fi mai ușor de citit de la bun început. Încerci să faci asta pe calea cea grea. WP_Query
nu este capabilă de logică complexă, iar logica complexă în SQL este greu de scris și greu de citit chiar și într-o zi bună.

sau poate un posts_join
http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join

Excluderea și includerea nu pot fi utilizate împreună, acest cod este folosit în nucleu, deci fie una, fie cealaltă.
...
if ( ! empty($r['include']) ) {
$incposts = wp_parse_id_list( $r['include'] );
$r['posts_per_page'] = count($incposts); // doar numărul de postări incluse
$r['post__in'] = $incposts;
} elseif ( ! empty($r['exclude']) )
...
Un query $wpdb este ușor dacă singurele argumente de care ai nevoie sunt doar cele pe care le-ai postat.
Această metodă este ușoară, dar dacă nu poți, poți explica de ce?
$exclude = array(1,2,3);
$include = array(3,4,5);
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 30,
'post__in' => array_diff($include, $exclude),
)
$posts = get_posts($args);

Știu că aș putea folosi array_diff() pe variabilele $exclude și $include, dar realitatea este mai complicată decât această întrebare. Trebuie făcut în interogare.

@s_ha_dum Îmi cer scuze, greșeala mea. Dă un vot negativ răspunsului, eu nu pot.

Am actualizat interogarea pentru a reflecta toți parametrii pe care îi folosesc. O interogare $wpdb ar putea fi cea mai bună soluție.

Am fost confuz de ce interogarea mea nu funcționa până când am citit Codex-ul despre WP_Query
. Poți folosi doar post__in
sau post__not_in
. Nu pe ambele împreună în aceeași interogare. Am găsit această soluție și trebuie să spun că este o soluție genială de ocolire a problemei.
