I'm trying to do a search in wordpress using a form with multiple fields (text, numeric and selects). The result page needs do show posts (with custom fields) filtered by this form.
The problem is: My result is not working well, and I can't display results by adding the search preferences. For example: I need to return a post that contains 3 values (property code, type of property, number of rooms) chosen in the search, but this does not happen, and the return always shows all registered posts.
How should I proceed to correctly filter my search, adding up the choices made in the form?
I tried to change the paremeters at the meta_query array, such like "relation", "type" or "compare", but not working...
My code (page-imoveis.php):
<?php
if( $_GET ){
query_posts( array(
'post_type' => 'post',
'order' => 'DESC',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'codigo',
'value' => $_GET['codigo'],
'compare' => '='
),
array(
'key' => 'tipo_venda',
'value' => $_GET['tipo-venda'],
'compare' => 'LIKE'
),
array(
'key' => 'tipo_de_imovel',
'value' => $_GET['tipo-imovel'],
'compare' => 'LIKE'
),
array(
'key' => 'cidade',
'value' => $_GET['cidade'],
'compare' => 'LIKE'
),
array(
'key' => 'bairro',
'value' => $_GET['bairro'],
'compare' => 'LIKE'
),
array(
'key' => 'quartos',
'value' => $_GET['quartos'],
'compare' => '='
),
array(
'key' => 'banheiros',
'value' => $_GET['banheiros'],
'compare' => '='
),
array(
'key' => 'suites',
'value' => $_GET['suites'],
'compare' => '='
),
array(
'key' => 'vagas',
'value' => $_GET['vagas'],
'compare' => '='
)
)
) );
} else{
query_posts( array(
'post_type' => 'post',
'order' => 'DESC',
'posts_per_page' => -1
) );
}
?>
<?php get_template_part('loop', 'imovel'); ?>
<?php wp_reset_query(); ?>
This is the loop page (loop-imovel.php):
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<div class="col-sm-6 col-xs-12 list-imovel">
<div class="box-imovel">
<span class="tag codigo">Cód.: <?php echo get_field('codigo'); ?></span>
<?php
$categoria = get_field("tipo_venda");
if ($categoria == 'Alugar') {
echo "<span class='tag alugar'>Alugar</span>";
} else {
echo "<span class='tag comprar'>Comprar</span>";
}
?>
<?php the_post_thumbnail('', array('class' => 'img-responsive')); ?>
<div class="info-imovel">
<span class="local">
<i class="fa fa-map-marker" aria-hidden="true"></i> <?php echo get_field('bairro'); ?>, <?php echo get_field('cidade'); ?>
</span>
<h4><?php the_title(); ?></h4>
<ul>
<li><i class="fa fa-bed" aria-hidden="true"></i> <?php echo get_field('quartos'); ?> quartos</li>
<li><i class="fa fa-tint" aria-hidden="true"></i> <?php echo get_field('banheiros'); ?> banheiros</li>
<li><i class="fa fa-car" aria-hidden="true"></i> <?php echo get_field('vagas'); ?> vagas</li>
<li><i class="fa fa-arrows-alt" aria-hidden="true"></i> <?php echo get_field('metragem'); ?> m<sup>2</sup></li>
</ul>
<hr>
<span class="preco">
R$<strong><?php echo get_field('valor'); ?></strong>
</span>
<a href="<?php the_permalink(); ?>" class="bt-cta">Saiba Mais</a>
</div>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
I'm pretty sure, given that you have an array with 8 options and have given an example with only 3, that you're giving the meta_query empty values and using LIKE to compare them, which of course will find everything.
Instead check that each expected value exists and is not empty before adding it to your meta_query.
We use if isset(...)
before checking a value is not empty to avoid generating errors, which may not be shown but would still exist.
We avoid writing the same code twice by setting up the query as a variable, rather than duplicating some of its content by calling query_posts()
in both the "if then" and the "else."
<?php
// set up the base query
$query = [
'post_type' => 'post',
'order' => 'DESC',
'posts_per_page' => -1,
];
if ( isset($_GET) && !empty($_GET) ) {
// create a list of things you're expecting and how they're being compared
$search = [
'codigo' => '=',
'tipo_venda' => 'LIKE',
'tipo_de_imovel' => 'LIKE',
'cidade' => 'LIKE',
'bairro' => 'LIKE',
'quartos' => '=',
'banheiros' => '=',
'suites' => '=',
'vagas' => '=',
];
// We need an empty array to fill
$meta_query = []; // by the way [] is the same as array()
// now see if they've actually been submitted
foreach ($search as $key => $compare) {
// Check if the node exists and that it's not empty
if ( isset($_GET[$key]) && !empty($_GET[$key]) ) {
// Append to meta query array
$meta_query[] = [
'key' => $key,
'value' => $_GET[$key],
'compare' => $compare,
];
}
}
// If there's anything in meta_query add it to your query
if ( !empty($meta_query) ) {
$meta_query['relation'] = 'AND'; // Don't forget to add this
$query['meta_query'] = $meta_query;
}
}
// Now run the query. It either has meta_query or it doesn't.
query_posts($query);
get_template_part('loop', 'imovel');
wp_reset_query();
?>