¿Usar post__in y post__not_in juntos?
Estoy tratando de mostrar solo las entradas que un usuario no ha visto, de esta manera:
$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);
Esperaría que esto devolviera las entradas 4 y 5, pero devuelve 3, 4 y 5.
¿Cómo establezco qué parámetro tiene preferencia entre 'post__in' y 'post__not_in'?
Sé que podría usar array_diff() en las variables $exclude y $include, pero la realidad es más complicada que esta pregunta. Tengo muchos arrays diferentes para comparar, y algunos de ellos son multidimensionales. También estoy incluyendo y excluyendo ciertas taxonomías.
También creo que es más fácil para otros leer si es una llamada WP_Query o $wpdb, en lugar de líneas y líneas de PHP para terminar con un parámetro de consulta.
Además, si array_diff es igual a un array vacío, entonces la consulta realmente devuelve entradas, no nada.
Entonces, ¿quizás la mejor manera sea una llamada $wpdb, o una forma de usar meta_query de WP_Query en el campo ID de la entrada?
post__in
y post__not_in
son mutuamente excluyentes.
Nota: no puedes combinar post__in y post__not_in en la misma consulta.
Tal como está escrita tu pregunta, la solución que rechazas (la de usar array_diff
) es la respuesta obvia.
Si es cierto que esa solución no funciona, necesitarás un filtro en posts_where
(probablemente) que proporcione la lógica de consulta que necesitas. Como no has explicado "la realidad [que] es más complicada que esta pregunta", realmente no es posible adivinar cuál podría ser esa lógica.
Pero aquí hay un ejemplo de un filtro posts_where
:
function smbd_cats_by_days ($where = '') {
// global $days_limit; // si es una variable
// $days_limit = DAYS_LIMIT; // si es una constante
// $days_limit = get_option('days_limit',100);
// tienes que descomentar una de las líneas anteriores,
// dependiendo de tu elección de mecanismos
$where .= " AND post_date < '" . date('y-m-d', strtotime("-{$days_limit} days")) . "'";
return $where;
}
add_filter('posts_where', 'smbd_cats_by_days');
Basado en la edición de la pregunta y en esta declaración de intención:
Estoy intentando mostrar solo publicaciones que un usuario no ha visto...
Escribe el PHP para crear un array de publicaciones que el usuario ha visto y exclúyelas con post__not_in
. Tu intento de meter todo en la consulta solo está complicando las cosas.
También creo que es más fácil de leer para otros si es una WP_Query o una llamada $wpdb, en lugar de líneas y líneas de PHP para terminar con un parámetro de consulta.
Para cuando escribas los filtros o el SQL para incluir todo en la consulta, no será más "legible" y es cuestionable si sería más legible en primer lugar. Estás intentando hacer esto de la manera difícil. WP_Query
no es capaz de lógica compleja y la lógica compleja en SQL es difícil de escribir y difícil de leer incluso en un buen día.

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

Exclude e include no pueden usarse juntos, este código se utiliza en el núcleo, por lo que es uno o el otro.
...
if ( ! empty($r['include']) ) {
$incposts = wp_parse_id_list( $r['include'] );
$r['posts_per_page'] = count($incposts); // solo el número de posts incluidos
$r['post__in'] = $incposts;
} elseif ( ! empty($r['exclude']) )
...
Una consulta $wpdb es fácil si los únicos argumentos que necesitas son solo los que has publicado.
Esta forma es fácil, pero ¿puedes explicar por qué no se puede hacer de otra manera?
$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);

Sé que podría usar array_diff() en las variables $exclude y $include, pero la realidad es más complicada que esta pregunta. Debe hacerse en la consulta.

@s_ha_dum Lo siento, error mío. Vota negativo la respuesta, no puedo hacerlo yo.

Actualicé la consulta para reflejar todos los parámetros que estoy usando. Una consulta con $wpdb podría ser la mejor opción.
