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've been hacking all day at a custom post type search/filter system. So far I have this:

function kdev_property_query($query) {

if(isset($_POST['rooms_n'])) $_SESSION['rooms_n'] = $_POST['rooms_n'];
if(isset($_POST['univer'])) $_SESSION['univer'] = $_POST['univer'];
if(isset($_POST['area_t'])) $_SESSION['area_t'] = $_POST['area_t'];

$query_post_type = $query->query_vars["post_type"];

if( !is_post_type_archive( 'properties' ) || $query_post_type == 'nav_menu_item' ) return;

//Show all available properties
$query->set('posts_per_page','-1');

$meta_query = array();
$tax_query = array();

global $query_string;
if(isset($_SESSION['rooms_n'])) $room_query = $_SESSION['rooms_n'];
if(isset($_SESSION['univer'])) $uni_query = $_SESSION['univer'];
if(isset($_SESSION['area_t'])) $area_query = $_SESSION['area_t'];

if(isset($room_query)) {
    $meta_query[] = array(
        'key' => '_rooms',
        'value' => $room_query
    );
}

if(isset($uni_query)) {
    $tax_query[] = array(
        'taxonomy' => 'university',
        'field' => 'slug',
        'terms' => $uni_query
    );
}

if(isset($area_query)) {
    $tax_query[] = array(
        'taxonomy' => 'area',
        'field' => 'slug',
        'terms' => $area_query
    );
}


if( ! empty( $meta_query ) )
        $query->set( 'meta_query', $meta_query );
if( ! empty( $tax_query ) )
        $query->set( 'tax_query', $tax_query );


}

add_action('pre_get_posts', 'kdev_property_query', 1);

I use the following form to search:

function display_area_university_filter_form(){
?>
<div id="search-filters">
<form method="post" action="">
<h3 id="property-search"><span>property search</span></h3>

<?php
    if(isset($_SESSION['univer'])) $uni = $_SESSION['univer'];
    else if(is_tax( 'university' ) ) $uni = get_query_var( 'term' );
    if(isset($uni)) $uni = strtolower($uni);?>
<p><label for="univer">University:</label> <select name="univer"><option value="NULL">Any</option>
<?php 
    $uni_terms =  get_categories('taxonomy=university'); 
    if (isset($uni)){
        foreach ($uni_terms as $term) {
            $option = '<option value="'.$term->slug.'"';
            if ($uni == $term->slug){
                $option.= ' selected="selected"';
            }
            $option .= '>'.$term->name;
            $option .= '</option>';
            echo $option;
        }
    }else{
        foreach ($uni_terms as $term) {
            $option = '<option value="'.$term->slug.'"';
            $option .= '>'.$term->name;
            $option .= '</option>';
            echo $option;
        }
    }
?>
</select>
</p>
<input type="hidden" name="custom_filter" value="area_uni">

<p>

    <?php
    if(isset($_SESSION['area_t'])) $area = $_SESSION['area_t'];
    else if(is_tax( 'area' ) ) $area = get_query_var( 'term' );
    if(isset($area)) $area = strtolower($area);?>
    <label for="area_t">Area:</label> 

    <select name="area_t">
        <option value="NULL">Any</option>
    <?php 
        $area_terms =  get_categories('taxonomy=area'); 
        if (isset($area)){
            foreach ($area_terms as $term) {
                $option = '<option value="'.$term->slug.'"';
                if ($area == $term->slug){
                    $option.= ' selected="selected"';
                }
                $option .= '>'.$term->name;
                $option .= '</option>';
                echo $option;
            }
        }else{
            foreach ($area_terms as $term) {
                $option = '<option value="'.$term->slug.'"';
                $option .= '>'.$term->name;
                $option .= '</option>';
                echo $option;
            }
        }
    ?>
    </select>
</p>

<p>
<?php 
if(isset($_SESSION['rooms_n'])) $rooms = $_SESSION['rooms_n'];

?>
    <label for="rooms_n">Bedrooms:</label> 
    <select name="rooms_n">
        <option value="NULL">Any</option>
        <?php 
        $room_array = array(3,4,5,6,7);
        foreach($room_array as $no) {
        $output = '<option ';
        if(isset($rooms) && $rooms == $no) $output .= 'selected="selected" ';
        $output .= 'value="'.$no.'">'.$no.'</option>';
        echo $output;
        } ?>

    </select>
</p>


<p><input class="<?php if(is_archive()) echo 'new-search '; ?>button" type="submit" name="search_props" value="<?php if(is_archive() || is_post_type_archive('properties')) echo 'New '; ?>Search"></p>

</form>
</div>
<?php

}

If I search for all three values at once (university, area and rooms) the page displays the correct results. However, if any or all of the option fields are left blank, then no posts are returned.

$GLOBALS['wp_query']->request is all options are selected returns:

SELECT   wp_posts.* FROM wp_posts  INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_relationships AS tt1 ON (wp_posts.ID = tt1.object_id) INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1  AND ( wp_term_relationships.term_taxonomy_id IN (5) AND tt1.term_taxonomy_id IN (18,15) ) AND wp_posts.post_type = 'properties' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND ( (wp_postmeta.meta_key = '_rooms' AND CAST(wp_postmeta.meta_value AS CHAR) = '4') ) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC 

...and if only university and rooms options are selected:

 SELECT   wp_posts.* FROM wp_posts  INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1  AND 0 = 1 AND wp_posts.post_type = 'properties' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND ( (wp_postmeta.meta_key = '_rooms' AND CAST(wp_postmeta.meta_value AS CHAR) = '4') ) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC 

Please help! This is killing me! If you need any more info please ask.

share|improve this question
    
Possibly because using NULL in your any selectors and it being rendered as a string. Try using <option value="">Any</option> instead and using !empty() instead of isset() –  Brady May 23 '12 at 19:32
    
@Brady that was it! Thanks! –  kdev May 24 '12 at 6:17
add comment

1 Answer

up vote 1 down vote accepted

On your search form you use NULL (as a string) for Any selection.

When the form is submitted it is sent as a string with the contents of the word null.

Your isset then sees that, its set and sets the session to null (as a string). Which in turn messes up your query.

To fix use:

<option value="">Any</option>

and check with:

!empty()
share|improve this answer
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.