Usare post__in e post__not_in insieme?
Sto cercando di mostrare solo i post che un utente non ha ancora visto, in questo modo:
$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);
Mi aspetterei che questo restituisca i post 4 e 5, ma restituisce 3, 4 e 5.
Come posso impostare quale parametro ha la precedenza tra 'post__in' e 'post__not_in'?
So che potrei usare array_diff() sulle variabili $exclude e $include, ma la realtà è più complicata di questa domanda. Ho molti array diversi da confrontare e alcuni di essi sono multidimensionali. Sto anche includendo ed escludendo determinate tassonomie.
Penso anche che sia più facile da leggere per gli altri se è una WP_Query o una chiamata $wpdb, piuttosto che righe e righe di PHP per ottenere un parametro di query.
Inoltre, se array_diff risulta in un array vuoto, la query restituisce effettivamente dei post invece di nulla.
Quindi forse il modo migliore è una chiamata $wpdb, oppure un modo per usare meta_query di WP_Query sul campo ID del post?
post__in
e post__not_in
si escludono a vicenda.
Nota: non puoi combinare post__in e post__not_in nella stessa query.
Come è scritta la tua domanda, la soluzione che rifiuti - quella di usare array_diff
- è la risposta ovvia.
Se è vero che quella soluzione non funziona, avrai bisogno di un filtro su posts_where
(probabilmente) che fornirà la logica della query di cui hai bisogno. Dato che non hai spiegato "la realtà [che] è più complicata di questa domanda", non è davvero possibile fare un'ipotesi su quale potrebbe essere quella logica.
Ma ecco un esempio di un filtro posts_where
:
function smbd_cats_by_days ($where = '') {
// global $days_limit; // se è una variabile
// $days_limit = DAYS_LIMIT; // se è una costante
// $days_limit = get_option('days_limit',100);
// devi decommentare una delle righe sopra,
// a seconda del meccanismo che scegli
$where .= " AND post_date < '" . date('y-m-d', strtotime("-{$days_limit} days")) . "'";
return $where;
}
add_filter('posts_where', 'smbd_cats_by_days');
In base alla modifica della domanda e a questa dichiarazione di intenti:
Sto cercando di mostrare solo i post che un utente non ha visto...
Scrivi il PHP per creare un array dei post che l'utente ha visto ed escludili con post__not_in
. Il tuo tentativo di inserire tutto nella query sta solo complicando le cose.
Penso anche che sia più facile da leggere per gli altri se è una chiamata WP_Query o $wpdb, piuttosto che righe e righe di PHP per arrivare a un parametro della query.
Quando avrai scritto i filtri e/o l'SQL per includere tutto nella query, non sarà più "leggibile" ed è discutibile se fosse più leggibile fin dall'inizio. Stai cercando di farlo nel modo più difficile. WP_Query
non è capace di logica complessa e la logica complessa in SQL è difficile da scrivere e da leggere anche nei giorni migliori.

o forse un posts_join
http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join

Exclude e include non possono essere usati insieme, questo codice è utilizzato nel core, quindi o uno o l'altro.
...
if ( ! empty($r['include']) ) {
$incposts = wp_parse_id_list( $r['include'] );
$r['posts_per_page'] = count($incposts); // solo il numero di post inclusi
$r['post__in'] = $incposts;
} elseif ( ! empty($r['exclude']) )
...
Una query $wpdb è semplice se gli unici argomenti necessari sono quelli che hai postato.
Questo modo è facile, ma se non riesci puoi spiegare perché?
$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);

So che potrei usare array_diff() sulle variabili $exclude e $include, ma la realtà è più complicata di questa domanda. Deve essere fatto nella query.

Ho aggiornato la query per riflettere tutti i parametri che sto usando. Una query $wpdb potrebbe essere la soluzione migliore.
