Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a custom post with a taxonomy associated to it. That taxonomy only has one term, and posts either belong to it or not, in a boolean fashion.

On the search results, I wish to show the custom posts that belong to the taxonomy, and not show the ones that don't belong. I've thought of two ways of accomplishing this, but I'm not sure which one is the best:

  • include only custom posts that belong to the taxonomy term;
  • exclude all custom posts that don't belong to the taxonomy term.

I've managed to do the exact opposite from what I want, with the following code:

global $query_string;
$query_args = explode("&", $query_string);
$search_query = array();
foreach($query_args as $key => $string) {
    $query_split = explode("=", $string);
    $search_query[$query_split[0]] = urldecode($query_split[1]);
}

$custom_query = array();
$custom_query['tax_query'][] = array( 'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'), 'field' => 'slug', 'operator' => 'NOT IN' );
$args = array_merge( $wp_query->query, $custom_query );
query_posts( $args );

$search = new WP_Query($search_query);

This, of course, outputs all the custom posts which are NOT IN the term-whatever. How can I accomplish the exact opposite?

EDIT

I will try to explain my problem a bit better. Let's use an example.

Imagine I have a taxonomy which is called "Selected" and only one taxonomy term called "Yes" that users can choose with a checkbox. I suppose I should have used two checkboxes ("Yes" and "No"), but I thought it didn't make much sense at the time.

When users search for something in the website, all pages, posts and custom posts appear in the results. The only thing I want to remove from the search results are the custom posts that are not associated with the taxonomy term "Yes", leaving all the rest like it is. This means I want to output all pages, posts and "Yes" custom posts.

Any ideas how I can achieve this? Thanks.

UPDATE

Here's an idea I had: Is there any way I can make two queries and merge the results?

  • One query with all the posts and pages except the custom post ('exclude_from_search' => true);
  • Other query with only the custom posts that match the taxonomy term ($custom_query['tax_query'][] = array( 'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'), 'field' => 'slug', 'operator' => 'IN' );).

However, if I use something like:

$mergedposts = array_merge( $wp_query->query, $custom_query );
query_posts( $mergedposts );

It will only show me the custom posts.

I suppose I could make a direct query with SQL but I've never worked with it. Although that is something I wish to learn in the future, right now it doesn't seem like a good way to solve this kind of problem, since I won't understand what I'm doing.

Right now my best option so far is create a new taxonomy term and classify all the "uncategorized" custom posts with it. However, they are a few hundreds, so it will take a while.

NEW UPDATE

I found a way to detect if a custom post belongs to a specific term in a taxonomy. This is a piece of code I picked up somewhere, since I don't have the PHP knowledge to create something like this all by myself. However, I understand what's being done and I adapted it to my situation.

function is_selected( $selected, $_post = null ) {
    if ( empty( $selected ) )
        return false;

    if ( $_post )
        $_post = get_post( $_post );
    else
        $_post =& $GLOBALS['post'];

    if ( !$_post )
        return false;

    $r = is_object_in_term( $_post->ID, 'selected', $selected );

    if ( is_wp_error( $r ) )
        return false;

    return $r;
}

This function will work correctly but only if used inside the loop. However, if I change the loop after the search query is made, it can mess up the pagination, and the number of results found will possibly be wrong.

Not sure if this is a step in the right direction, but at least it's a step.

share|improve this question
    
change 'operator' => 'NOT IN' to 'operator' => 'IN' –  Mridul Aggarwal Oct 16 '12 at 11:11
    
That will, of course, only show custom posts and hide all the rest. That's not what I'm looking for. –  Cthulhu Oct 16 '12 at 11:13
1  
Just a thought, when attaching information like this to a post(a yes/no), in my experience its better to store this information in the postmeta table. I don't necessarily have the full picture so that might not have been the better solution, but querying for this information on postmeta would have made for a much easier and simpler query –  Macgyver Oct 18 '12 at 14:32
add comment

1 Answer

up vote 5 down vote accepted
+50

After reading your revised question it was easier to comprehend what you are trying to do. My new solution looks like the thing you wanted to do in the first place: it just excludes all posts which are of your custom type but don't have the "yes"-term associated with it:

$custom_query = array();
$custom_query['post_type'] = 'any';

// first, query all the posts of your custom type
// that don't have the "yes"-term:
$tmp_wp_query = new WP_Query(array(
    'posts_per_page' => -1,
    'fields' => 'ids',
    'post_type' => 'your-post-type',
    'tax_query' => array(array(
        'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'),
        'field' => 'slug', 'operator' => 'NOT IN'
    ))
));

if(!empty($tmp_wp_query->posts)) {
    // Exclude the "yes"-less posts from the actual post query
    $custom_query['post__not_in'] = $tmp_wp_query->posts;
}

// now proceed with your original code and execute the definitive query
$args = array_merge( $wp_query->query, $custom_query );
query_posts( $args );

$search = new WP_Query($search_query);

The only downside is, that there are now two queries to run. But the first query is relatively light-weight so the performance-loss should not be that huge.

share|improve this answer
    
Thank you for your help, but I guess I didn't explain myself very well. I edited my question with an example. –  Cthulhu Oct 17 '12 at 9:36
    
@Cthulhu: thanks for your response - I have now revised my answer. –  vstm Oct 19 '12 at 16:52
    
That was absolutelly perfect. Thank you very much! –  Cthulhu Oct 22 '12 at 9:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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