it-swarm.com.de

Benutze post__in und post__not_in zusammen?

Ich versuche nur Beiträge anzuzeigen, die ein Benutzer noch nicht gesehen hat:

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

Ich würde erwarten, dass dies die Posts 4 und 5 zurückgibt, aber es gibt 3, 4 und 5 zurück.

Wie stelle ich ein, welche Einstellung zwischen den Parametern 'post _ in' und 'post _ not_in' bevorzugt wird?

Ich weiß, dass ich array_diff () für die Variablen $ exclude und $ include verwenden könnte, aber die Realität ist komplizierter als diese Frage. Ich kann mit vielen verschiedenen Arrays vergleichen, von denen einige mehrdimensional sind. Ich schließe auch bestimmte Taxonomien ein und aus.

Ich denke auch, dass es für andere einfacher ist, zu lesen, ob es sich um einen WP_Query- oder $ wpdb-Aufruf handelt, anstatt Zeilen und Zeilen von PHP, um einen Abfrageparameter zu erhalten.

Wenn array_diff gleich einem leeren Array ist, gibt die Abfrage tatsächlich Posts zurück, nicht nichts.

Vielleicht ist der beste Weg also ein $ wpdb-Aufruf oder eine Möglichkeit, die meta_query von WP_Query im Feld post ID zu verwenden?

1
Drew Baker

post__in und post__not_in schließen sich gegenseitig aus.

Hinweis: Sie können post__in und post__not_in nicht in derselben Abfrage kombinieren.

http://codex.wordpress.org/Class_Reference/WP_Query

Während Ihre Frage geschrieben ist, ist die Lösung, die Sie ablehnen - die Verwendung von array_diff - die offensichtliche Antwort.

Wenn es stimmt, dass diese Lösung nicht funktioniert, benötigen Sie einen Filter für posts_where (wahrscheinlich), der die von Ihnen benötigte Abfragelogik bereitstellt. Da Sie nicht erklärt haben, "die Realität ist komplizierter als diese Frage", ist es wirklich nicht möglich, eine Vermutung anzustellen, wie diese Logik aussehen könnte.

Aber hier ist ein Beispiel für einen posts_where Filter:

function smbd_cats_by_days ($where = '') {
    // global $days_limit; // if a variable
    // $days_limit = DAYS_LIMIT; // if a constant
    // $days_limit = get_option('days_limit',100);
    // you have to uncomment one of the above, 
    // depending on your choice of mechanisms
    $where .= " AND post_date < '" . date('y-m-d', strtotime("-{$days_limit} days")) . "'";
    return $where;
}
add_filter('posts_where', 'smbd_cats_by_days');

Gestützt auf die Bearbeitung der Frage und auf diese Absichtserklärung:

Ich versuche nur Beiträge anzuzeigen, die ein Benutzer noch nicht gesehen hat ...

Schreiben Sie das PHP, um eine Reihe von Posts zu erstellen, die der Benutzer gesehen hat, und schließen Sie sie mit post__not_in aus. Ihr Versuch, alles in die Abfrage einzuschieben, macht die Sache nur komplizierter.

Ich denke auch, dass es für andere einfacher ist, zu lesen, ob es sich um einen WP_Query- oder $ wpdb-Aufruf handelt, anstatt Zeilen und Zeilen von PHP, um einen Abfrageparameter zu erhalten.

Wenn Sie die Filter und/oder SQL-Anweisungen schreiben, um alles in die Abfrage aufzunehmen, ist sie nicht mehr "lesbar" und es ist fraglich, ob sie überhaupt besser lesbar sind. Du versuchst es auf die harte Tour. WP_Query ist nicht in der Lage, komplexe Logik zu erstellen, und komplexe Logik in SQl ist selbst an einem guten Tag schwer zu schreiben und schwer zu lesen.

4
s_ha_dum

Excude und Include können nicht zusammen verwendet werden, dieser Code wird in core verwendet, also in dem einen oder anderen.

...
if ( ! empty($r['include']) ) {
  $incposts = wp_parse_id_list( $r['include'] );
  $r['posts_per_page'] = count($incposts);  // only the number of posts included
  $r['post__in'] = $incposts;
} elseif ( ! empty($r['exclude']) )
...

Eine $ wpdb-Abfrage ist einfach, wenn Sie nur die von Ihnen geposteten Argumente benötigen.

Dieser Weg ist einfach, aber wenn Sie nicht erklären können, warum?

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