Forma elegante de incluir solo posts publicados con get_objects_in_term()?
La forma obvia es iterar a través del array resultante de IDs, usar get_post para cada uno y verificar post_status == 'publish'
. Pero me pregunto si esto podría causar problemas de memoria ya que get_post
intentará por defecto cachear cada resultado. ¿Existen argumentos ocultos que se puedan pasar a get_objects_in_term()
o alguna otra función de taxonomía que no esté utilizando? ¿O sería necesaria una consulta SQL personalizada con JOIN?

¡Gracias por la respuesta! El problema con el que estoy lidiando es el almacenamiento en caché, que definitivamente ocurrirá si usamos WP_Query en cualquiera de sus formas. get_objects_in_term() es mucho más ligero porque solo devuelve IDs de posts. Por otro lado, no puedes pasarle parámetros de post_status en los argumentos. Ay.

No hay argumentos que puedas pasar. El único argumento que se utiliza es order
. Aquí está el código fuente de la función:
<?php
function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
global $wpdb;
if ( ! is_array( $term_ids ) )
$term_ids = array( $term_ids );
if ( ! is_array( $taxonomies ) )
$taxonomies = array( $taxonomies );
foreach ( (array) $taxonomies as $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) )
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomía inválida' ) );
}
$defaults = array( 'order' => 'ASC' );
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
$order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC';
$term_ids = array_map('intval', $term_ids );
$taxonomies = "'" . implode( "', '", $taxonomies ) . "'";
$term_ids = "'" . implode( "', '", $term_ids ) . "'";
$object_ids = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($term_ids) ORDER BY tr.object_id $order");
if ( ! $object_ids )
return array();
return $object_ids;
}
Sin embargo, puedes copiar la función y agregar una cláusula adicional para usar el estado del post.
<?php
function wpse29749_get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
global $wpdb;
if ( ! is_array( $term_ids ) )
$term_ids = array( $term_ids );
if ( ! is_array( $taxonomies ) )
$taxonomies = array( $taxonomies );
foreach ( (array) $taxonomies as $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) )
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomía inválida' ) );
}
$defaults = array( 'post_status' => 'publish', 'order' => 'ASC' );
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
$order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC';
$term_ids = array_map('intval', $term_ids );
$taxonomies = "'" . implode( "', '", $taxonomies ) . "'";
$term_ids = "'" . implode( "', '", $term_ids ) . "'";
$object_ids = $wpdb->get_col( $wpdb->prepare(
"SELECT ID from $wpdb->posts WHERE ID IN (
SELECT tr.object_id FROM $wpdb->term_relationships
AS tr INNER JOIN $wpdb->term_taxonomy AS tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id
WHERE tt.taxonomy IN ($taxonomies)
AND tt.term_id IN ($term_ids)
) AND post_status = %s
ORDER BY ID $order", $post_status ) );
if ( ! $object_ids )
return array();
return $object_ids;
}
No hay mucha diferencia. Un elemento adicional en los $defaults
así como algunas modificaciones al SQL.
