FutureMedia
2/25/2018 - 1:02 PM

Customising WP search for Properties

Create predefined custom queries search using custom args using add_filter and pre_get_posts https://www.smashingmagazine.com/2016/03/advanced-wordpress-search-with-wp_query/

There is more on the site.

function sm_setup() {
    add_shortcode( 'sm_search_form', 'sm_search_form' );
}
add_action( 'init', 'sm_setup' );


function sm_search_form( $args ){
    // our code here
}

// The Query
// meta_query expects nested arrays even if you only have one query
$sm_query = new WP_Query( array( 'post_type' => 'accommodation', 'posts_per_page' => '-1', 'meta_query' => array( array( 'key' => '_sm_accommodation_area' ) ) ) );

// The Loop
if ( $sm_query->have_posts() ) {
    $areas = array();
    while ( $sm_query->have_posts() ) {
        $sm_query->the_post();
        $area = get_post_meta( get_the_ID(), '_sm_accommodation_area', true );

        // populate an array of all occurrences (non duplicated)
        if( !in_array( $area, $areas ) ){
            $areas[] = $area;    
        }
    }
}
} else{
       echo 'No accommodations yet!';
       return;
}

/* Restore original Post Data */
wp_reset_postdata();

if( count($areas) == 0){
    return;
}

asort($areas);

$select_area = '<select name="area" style="width: 100%">';
$select_area .= '<option value="" selected="selected">' . __( 'Select area', 'smashing_plugin' ) . '</option>';
foreach ($areas as $area ) {
    $select_city .= '<option value="' . $city . '">' . $area . '</option>';
}
$select_area .= '</select>' . "\n";

reset($areas);

/**
 * Register custom query vars
 *
 * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/query_vars
 */
 
function sm_register_query_vars( $vars ) {
    $vars[] = 'type';
    $vars[] = 'area';
    return $vars;
} 
add_filter( 'query_vars', 'sm_register_query_vars' );

/**
 * Build a custom query based on several conditions
 * The pre_get_posts action gives developers access to the $query object by reference
 * any changes you make to $query are made directly to the original object - no return value is requested
 *
 * @link https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts
 *
 */
function sm_pre_get_posts( $query ) {
    // check if the user is requesting an admin page 
    // or current query is not the main query
    if ( is_admin() || ! $query->is_main_query() ){
        return;
    }

    // edit the query only when post type is 'accommodation'
    // if it isn't, return
    if ( !is_post_type_archive( 'accommodation' ) ){
        return;
    }

    $meta_query = array();

    // add meta_query elements
    if( !empty( get_query_var( 'area' ) ) ){
        $meta_query[] = array( 'key' => '_sm_accommodation_area', 'value' => get_query_var( 'area' ), 'compare' => 'LIKE' );
    }

    if( !empty( get_query_var( 'type' ) ) ){
        $meta_query[] = array( 'key' => '_sm_accommodation_type', 'value' => get_query_var( 'type' ), 'compare' => 'LIKE' );
    }

    if( count( $meta_query ) > 1 ){
        $meta_query['relation'] = 'AND';
    }

    if( count( $meta_query ) > 0 ){
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'sm_pre_get_posts', 1 );
You can search the site like this:
http://example.com/?type=apartment&area=athens