web-dev-qa-db-fra.com

Utilisez post__in et post__not_in ensemble?

J'essaie de ne montrer que les messages qu'un utilisateur n'a pas vus, comme ceci:

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

Je m'attendrais à ce que cela retourne les postes 4 et 5, mais les retours 3, 4 et 5.

Comment définir les préférences entre "post _ in" et les paramètres "post _ not_in"?

Je sais que je pourrais utiliser array_diff () sur les variables $ exclude et $ include, mais la réalité est plus compliquée que cette question. J'ai de nombreux tableaux différents à comparer, et certains d'entre eux sont multidimensionnels. J'inclus et exclure également certaines taxonomies.

Je pense aussi qu'il est plus facile pour les autres de lire s'il s'agit d'un appel WP_Query ou $ wpdb, plutôt que des lignes et des lignes de PHP pour se retrouver avec un paramètre de requête.

De même, si array_diff est égal à un tableau vide, la requête renvoie en fait des publications, pas rien.

Alors peut-être que le meilleur moyen est un appel à $ wpdb ou un moyen d'utiliser la meta_query de WP_Query dans le champ ID du message?

1
Drew Baker

post__in et post__not_in sont mutuellement exclusifs.

Remarque: vous ne pouvez pas combiner post__in et post__not_in dans la même requête.

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

Au moment où votre question est écrite, la solution que vous rejetez - celle d'utiliser array_diff-- - est la réponse évidente.

S'il est vrai que cette solution ne fonctionnera pas, vous aurez besoin d'un filtre sur posts_where (probablement) qui fournira la logique de requête dont vous avez besoin. Comme vous n'avez pas expliqué "la réalité [qui] est plus compliquée que cette question", il n'est vraiment pas possible de deviner quelle pourrait être cette logique.

Mais voici un exemple de 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');

Sur la base de la modification de la question et de la présente déclaration d'intention:

J'essaie de ne montrer que les messages qu'un utilisateur n'a pas vus ...

Écrivez PHP pour créer un tableau de publications que l'utilisateur a vues et excluez-les avec post__not_in. Votre tentative de tout mettre dans la requête ne fait que compliquer les choses.

Je pense aussi qu'il est plus facile pour les autres de lire s'il s'agit d'un appel WP_Query ou $ wpdb, plutôt que des lignes et des lignes de PHP pour se retrouver avec un paramètre de requête.

Au moment où vous écrivez les filtres et/ou SQL pour inclure tout dans la requête, il ne sera pas plus "lisible" et il est douteux que ce soit plus lisible en premier lieu. Vous essayez de faire cela à la dure. WP_Query n'est pas capable de logique complexe et la logique complexe en SQl est difficile à écrire et difficile à lire, même lors d'une bonne journée.

4
s_ha_dum

Excude et include ne peuvent pas être utilisés ensemble, ce code est utilisé en noyau, donc ou l’un ou l’autre.

...
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']) )
...

Une requête $ wpdb est facile si les seuls arguments dont vous avez besoin sont uniquement ceux que vous avez publiés.

C'est facile, mais si vous ne pouvez pas expliquer pourquoi?

$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