Usare post__in e post__not_in insieme?

2 ago 2013, 05:13:30
Visualizzazioni: 22.6K
Voti: 1

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?

4
Commenti

Potresti per favore spiegare la complessa realtà?

s_ha_dum s_ha_dum
2 ago 2013 06:13:38

Aggiornato per spiegare perché preferirei non usare array_diff se possibile. Penso che un approccio con $wpdb potrebbe essere la soluzione migliore.

Drew Baker Drew Baker
2 ago 2013 08:22:19

@DrewBaker Ancora non capisco una cosa. Tu dici: Ho molti array diversi da confrontare, e alcuni di essi sono multidimensionali Ma per usare include e exclude devi passare un array piatto di id. Quindi fai qualche logica per estrarre due array piatti dagli array diversi e multidimensionali? Se è così, puoi effettivamente eseguire array_diff e se il risultato è vuoto puoi usare un if e non eseguire mai la query, $posts = ! empty($diff) ? get_posts($args) : array();

gmazzap gmazzap
2 ago 2013 12:40:56

OK, ho capito quello che state dicendo. Utilizzerò array_diff(). Grazie!

Drew Baker Drew Baker
2 ago 2013 20:18:19
Tutte le risposte alla domanda 2
2

post__in e post__not_in si escludono a vicenda.

Nota: non puoi combinare post__in e post__not_in nella stessa query.

http://codex.wordpress.org/Class_Reference/WP_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.

2 ago 2013 06:25:02
Commenti

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

gmazzap gmazzap
2 ago 2013 06:29:52

Grazie, ho capito. Allora userò array_diff(). Grazie. Ho votato positivamente questa risposta perché hai lavorato duramente per rispondere alla mia domanda mal formulata.

Drew Baker Drew Baker
2 ago 2013 20:19:02
4

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);
2 ago 2013 05:40:23
Commenti

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

s_ha_dum s_ha_dum
2 ago 2013 06:11:43

@s_ha_dum Scusa, colpa mia. Non posso downvotare la risposta.

gmazzap gmazzap
2 ago 2013 06:13:02

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

Drew Baker Drew Baker
2 ago 2013 08:29:26

Ero confuso sul perché la mia query non funzionasse finché non ho letto il Codex riguardo a WP_Query. Puoi usare solo post__in o post__not_in. Non entrambi insieme nella stessa query. Ho trovato questa soluzione, e devo dire che è un'ottima soluzione alternativa.

Michael Ecklund Michael Ecklund
1 nov 2017 18:15:43