4

The obvious way is to iterate through the resulting array of IDs, get_post for each and test against post_status == 'publish'. But I wonder whether this could cause memory issues since get_post will attempt by default to cache each result? Short of a custom SQL join, are there any surprise args one can pass to get_objects_in_term() or is there some other tax function I'm not leveraging that I should be?

7

You can add 'post_status' => 'publish' in your query to retrieve only objects with status publish , this will work for get_posts, query_posts or $wp_query and to include also custom taxonomies you can use tax_query in your args list

| improve this answer | |
  • Thanks for the answer! The issue I'm wrestling with is the cacheing, which will definitely occur if we use WP_Query in any of its forms. get_objects_in_term() is much more lean because it's only returning post IDs. On the downside, you can't pass it any post_status parameters in the arguments. alas. – Tom Auger Sep 28 '11 at 19:33
2

There's no arguments you can pass in. The only argument that does get used is order. Here's the source of the function:

<?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', __( 'Invalid taxonomy' ) );
    }

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

You can, however, copy the function and add in an additional clause to use the post status.

<?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', __( 'Invalid taxonomy' ) );
    }

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

Not much different. An additional element in the $defaults as well as some modifications to the SQL.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.