1

I'm desperately trying to make an advanced searchform in order to get posts by their meta fields. I got this:

[UPDATE]: This is the correct code:

/**
*Registering custom query vars
*
*/

function sy_register_query_var( $vars ){
  $vars[] = 'type';
  $vars[] = 'cabins';
  $vars[] = 'base';
  return $vars;
}
add_filter( 'query_vars', 'sy_register_query_var' );

<?php

/**
*Registering custom query vars
*
*/

function sy_register_query_var( $vars ){
$vars[] = 'type';
$vars[] = 'people';
$vars[] = 'base';
$vars[] = 'duration';

return $vars;
}
add_filter( 'query_vars', 'sy_register_query_var' );

/**
* 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
*
*/

function sy_pre_get_posts( $query ){
if( is_admin() || ! $query->is_main_query() ){
return;
}
$query->set( 'type', get_query_var( 'type' ) );
$query->set( 'people', get_query_var( 'people' ) );
$query->set( 'base', get_query_var( 'base' ) );
$query->set( 'duration', get_query_var( 'duration' ) ); 

if( !is_post_type_archive( 'fleet' ) ){
return;
}

$meta_query = array();

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

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

if( count( $meta_query ) > 0 ){
$query->set( 'meta_query', array($meta_query) );
}

}

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

function sy_search_form(){

$select_type = '<select name="type" style="width: 100%">';
$select_type .= '<option value="" selected="selected">' . __( 'Type', 'syacht' ) . '</option>';
$select_type .= '<option value="Motor">' . __( 'Motor', 'syacht' ) . '</option>';
$select_type .= '<option value="Sailing">' . __( 'Sailing', 'syacht' ) . '</option>';
$select_type .= '<option value="Ribs">' . __( 'Ribs', 'syacht' ) . '</option>';
$select_type .= '<option value="Caiques">' . __( 'Caiques', 'syacht' ) . '</option>';
$select_type .= '<option value="Speed Boats">' . __( 'Spead Boats', 'syacht' ) . '</option>';
$select_type .= '</select>' . "\n";

$select_people = '<select name="people" style="width: 100%">';
$select_people .= '<option value="" selected="selected">' . __( 'People', 'syacht' ) . '</option>';
$select_people .= '<option value="3 or less">' . __( '3 or less', 'syacht' ) . '</option>';
$select_people .= '<option value="4-6">' . __( '4-6', 'syacht' ) . '</option>';
$select_people .= '<option value="6 or more">' . __( '6 or more', 'syacht' ) . '</option>';
$select_people .= '</select>' . "\n";

$select_base = '<select name="base" style="width: 100%">';
$select_base .= '<option value="" selected="selected">' . __( 'Base', 'syacht' ) . '</option>';
$select_base .= '<option value="Mykonos">' . __( 'Mykonos', 'syacht' ) . '</option>';
$select_base .= '<option value="Old Port">' . __( 'Old Port', 'syacht' ) . '</option>';
$select_base .= '</select>' . "\n";

$select_duration = '<select name="duration" style="width: 100%">';
$select_duration .= '<option value="" selected="selected">' . __( 'Duration', 'syacht' ) . '</option>';
$select_duration .= '<option value="1 to 3 days">' . __( '1 to 3 days', 'syacht' ) . '</option>';
$select_duration .= '<option value="1 week">' . __( '1 week', 'syacht' ) . '</option>';
$select_duration .= '<option value="2 weeks">' . __( '2 weeks', 'syacht' ) . '</option>';
$select_duration .= '</select>' . "\n";

$output = '<form class="advanced-search" action="' . esc_url( home_url() ) . '" method="get" role="search">';
$output .= '<div class="wrap">';
$output .= '<div>'.  $select_type  . '</div>';
$output .= '<div>'.  $select_people  . '</div>';
$output .= '<div>'.  $select_base  . '</div>';
$output .= '<div>'.  $select_duration . '</div>';
$output .= '<input type="hidden" name="post_type" value="fleet" />';
$output .= '<div><input type="submit" id="as-submit" class="button gold full" value="Search yachts" /></div>';
$output .= '<a href="javascript:void(0)" class="search-hide" title="Hide this box">Hide this box</a>';
$output .= '</div></form>';

return $output;
}

Actually this form works, but not at all. In fact, the search page shows all posts belonging to "fleet" custom post type and they are not filtered by the search terms I set. Why this? Where is the error? Please it's been days since I've started trying to solve this. Thanks all.

P.s.: Please, do not suggest any plugin. I've tried already many, and none of them worked.

2 Answers 2

0

The meta_query parameter must be an array of array if you want to add relation between different key, even they only one key to grab.

So $query->set( 'meta_query', $meta_query );

Must be

$query->set( 'meta_query', array($meta_query) );

You can have a look to WP_Query for more details.

Hope it helps and work, I just look for this details ;-)

1
  • I solved the problem, but now I have another one. If none of the fields of the search form is filled and I press "Search", the search page is the "archive", I don't know why. Plus, it shows me results of his choice, with which criteria I can't say. Is there a way to say it to show me all the items in the database instead? I updated the code with the correct one. Jun 5, 2017 at 9:36
0

Advance unlimited search by tax_query and meta_query

// set all common parameters
$args = array(
    'post_type'             => 'property',
    'posts_per_page'        => 3,
    'orderby'               => 'ASC',
    'meta_query'            => [],
    'tax_query'             => []
);

// set meta_query parameters
if ( $property_bedrooms) {
    $args['meta_query'][] = [
        array(
            'key'     => 'property_bedrooms',
            'value'   => $property_bedrooms,
            'compare' => 'IN',
        ),
    ];
}
if ( $property_bathrooms) {
    $args['meta_query'][] = [
        array(
            'key'     => 'property_bathrooms',
            'value'   => $property_bathrooms,
            'compare' => 'IN',
        ),
    ];
}
// set tax_queryparameters
if ( $property_city) {
    $args['tax_query'][] = [
        array(
            'taxonomy'  => 'property_city', 
            'field'     => 'name', 
            'terms'     => $property_city,
            'operator'  => 'IN'
        ),
    ];
}
if ( $property_type) {
    $args['tax_query'][] = [
        array(
            'taxonomy'  => 'property_type', 
            'field'     => 'slug', 
            'terms'     => $property_type,
            'operator'  => 'IN'
        ),
    ];
}
$query = new WP_Query( $args );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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