I'm a junior developer who is currently developing a Wordpress site that requires a hand-made, powerful search form.
I have a bunch of parent SIMPLE (normal, not custom) categories (Customers, Business Sectors, Operations and Business Areas), and then I've got some children categories (for example, the customer "TEST" is a subcategory of Customers, so you can understand me). Then, I categorize all of the posts according to the customer they belong, their business sector, area, etc. so every post has its categories.
In my search form, I've got the different subcategories PRELOADED in the header (no AJAX required), and attached to different SELECTS. Every select option has the "value" of the ID of the subcategory, so that's all good.
The thing is, the form can be sent totally EMPTY, searching only for specific words (classic Wordpress search), or picking some of the categories from the dropdown (which should be something like "in__category" for the WP_Query), or BOTH WORDS AND CATEGORIES.
Now, to the point: I've used WP_Query to search for Posts, first getting the parameters that are sent by the form, and then trying to add the arguments to the WP_Query, but I am not getting the expected results.
There is an specific case that is bothering me: I have a customer named "Starbucks", for example. If I search for "starbuck", I get about 5-6 posts that contain "Starbucks" in the title, but if I search for "Starbucks", I only get ONE POST using my current WP_Query.
Here is the code of my advanced-searchform.php
<?php
//Función getSelectItems en functions.php, dado el SLUG de la categoria, obtiene las subcategorias hijas de la categoria del slug.
$sectores = getSelectItems('sectores');
$clientes = getSelectItems('clientes');
$areas = getSelectItems('areas-de-especializacion');
$operaciones = getSelectItems('operaciones');
$titulos = getAllPostTitles();
?>
<form method="post" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<!-- PASSING THIS TO TRIGGER THE ADVANCED SEARCH RESULT PAGE FROM functions.php -->
<input type="hidden" name="search" value="advanced">
<input type="search" id="acexito" class="acexito search-field" name="s" placeholder="<?php _e( '¿qué estás buscando?...', 'textdomain' ); ?>" value="<?php get_search_query(); ?>"/>
<button type="button" id="btnfiltros" class="btnfiltros btnclaro"></button>
<div id="filtros" class="filtros">
<div class="rowfilter">
<label for="area" class="leftinput"><?php _e( 'Área', 'textdomain' ); ?></label>
<select class="iptfiltro" name="area[]" id="area" multiple="multiple">
<?php
for($i=0;$i<count($areas);$i++){
?>
<option value="<?php echo $areas[$i]['id'];?>"><?php echo $areas[$i]['name'];?></option>
<?php
}
?>
</select>
</div>
<div id="rowcliente" class="rowfilter">
<label for="cliente" class="leftinput"><?php _e( 'Cliente', 'textdomain' ); ?></label>
<select class="iptfiltro" name="cliente[]" id="cliente" multiple="multiple">
<?php
for($i=0;$i<count($clientes);$i++){
?>
<option value="<?php echo $clientes[$i]['id'];?>"><?php echo $clientes[$i]['name'];?></option>
<?php
}
?>
</select>
</div>
<div id="rowsector" class="rowfilter">
<label for="sector" class="leftinput"><?php _e( 'Sector', 'textdomain' ); ?></label>
<!--<input type="text" name="sector" id="sector" class="iptfiltro"/>-->
<select class="iptfiltro" name="sector[]" id="sector" multiple="multiple">
<?php
for($i=0;$i<count($sectores);$i++){
?>
<option value="<?php echo $sectores[$i]['id'];?>"><?php echo $sectores[$i]['name'];?></option>
<?php
}
?>
</select>
</div>
<div class="rowfilter">
<label for="operacion" class="leftinput"><?php _e( 'Operación', 'textdomain' ); ?></label>
<select class="iptfiltro" name="operacion[]" id="operacion" multiple="multiple">
<?php
for($i=0;$i<count($operaciones);$i++){
?>
<option value="<?php echo $operaciones[$i]['id'];?>"><?php echo $operaciones[$i]['name'];?></option>
<?php
}
?>
</select>
</div>
<div class="rowfilter fecha" id="rowini">
<label for="fechaini" id="labelfecha" class="leftinput"><?php _e( 'Fecha', 'textdomain' ); ?></label>
<!--<label id="labelini" for="fechaini" class="leftinput"><?php //_e( 'Inicio', 'textdomain' ); ?></label>-->
<input type="text" name="fechaini" id="fechaini" class="iptfiltro" placeholder="<?php _e( 'Inicio', 'textdomain' ); ?>"/>
<!--<label id="labelfin" class="leftinput"><?php //_e( 'Fin', 'textdomain' ); ?></label>-->
<input type="text" name="fechafin" id="fechafin" class="iptfiltro" placeholder="<?php _e( 'Fin', 'textdomain' ); ?>"/>
</div>
</div>
<input type="submit" id="submitsearch" class="submitsearch" value="Buscar"/>
</form>
Then, here is the content of my functions.php file
//Obtain categories for preloading
function getSelectItems($slugcategoria){
$categoria = get_category_by_slug($slugcategoria);
$args = array(
'child_of' => $categoria->term_id,
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => FALSE,
'hierarchical' => 1,
'taxonomy' => 'category'
);
$child_categories = get_categories($args);
$items = array();
foreach($child_categories as $cat){
$desglose = array(
'id' => $cat->cat_ID,
'name' => $cat->name
);
array_push($items, $desglose);
}
return $items;
}
function customSearchByParams($keywords,$clientes,$areas,$sectores,$operaciones,$fechaini,$fechafin){
//Crear array de IDs de categoria previamente
//Wordpress - fecha formato Y-m-d
$cats = array();
//Add "customers" to the query
if(!empty($clientes)){
for($i=0;$i<count($clientes);$i++){
array_push($cats, $clientes[$i]);
}
}
//Add "business areas" to the query
if(!empty($areas)){
for($i=0;$i<count($areas);$i++){
array_push($cats, $areas[$i]);
}
}
//Add "business sectors" to the query
if(!empty($sectores)){
for($i=0;$i<count($sectores);$i++){
array_push($cats, $sectores[$i]);
}
}
//Add items from "operation" subcategories
if(!empty($operaciones)){
for($i=0;$i<count($operaciones);$i++){
array_push($cats, $operaciones[$i]);
}
}
/*I check for "--" because my datepicker library sends "--" if nothing was selected*/
//Filter by date
if($fechaini=="--" && $fechafin=="--"){
//No dates
$args = array(
'category__in' => $cats
);
}else if($fechaini!="--" && $fechafin=="--"){
//Only posts after given date
$partsini = explode("-", $fechaini);
$args = array(
'category__in' => $cats,
'date_query' => array(
array(
'after' => array(
'year' => $partsini[0],
'month' => $partsini[1],
'day' => $partsini[2],
),
'inclusive' => true
)
)
);
}else if($fechaini=="--" && $fechafin!="--"){
//Only posts before given date
$partsfin = explode("-", $fechafin);
$args = array(
'category__in' => $cats,
'date_query' => array(
array(
'before' => array(
'year' => $partsfin[0],
'month' => $partsfin[1],
'day' => $partsfin[2],
),
'inclusive' => true
)
)
);
}else{
//Both (date in between two given dates)
$partsini = explode("-", $fechaini);
$partsfin = explode("-", $fechafin);
$args = array(
'category__in' => $cats,
'date_query' => array(
array(
'after' => array(
'year' => $partsini[0],
'month' => $partsini[1],
'day' => $partsini[2],
),
'before' => array(
'year' => $partsfin[0],
'month' => $partsfin[1],
'day' => $partsfin[2],
),
'inclusive' => true,
'relation' => 'AND'
)
)
);
}
if(!empty($keywords)){
$args['s'] = $keywords;
$words = explode(" ", $keywords);
foreach($words as $word){
$slug = slugify($word);
$categoria = get_category_by_slug($slug);
if(!empty($categoria)){
array_push($cats, $categoria->cat_ID);
}
}
$args['category__in'] = $cats;
}
$args['posts_per_page'] = 10;
$args['nopaging'] = false;
$args['paged'] = false;
$the_query = new WP_Query($args);
return $the_query;
}
This last function elaborates the WP_Query that I use later on and output with a template accordingly. The thing I want to get fixed is the Query, basically, I need it to be smart and powerful.
I've read the documentation, and tried some stuff myself. I wanted to stick to WP_Query, as I'm totally lost when it comes to the WP Database itself, I wanted to avoid using pure MySQL queries for fetching the posts.
How can I get this working? My current version works, but it could be done much better I think. Any advice is appreciated.