I am trying to apply filters in a list of products. Users will use select boxes on the front end and click a button to filter the products.
Every product is it's own post, so I use WP_Query to get the posts. For example, I want all products with the color "red", the material "plastic" and the brand "Bikon". So I use;
$color = "red";
$material = "plastic";
$brand = "Bikon";
$query = new WP_Query(array(
'post_type' => 'products',
'posts_per_page' => 6,
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'color',
'value' => $color,
'compare' => '='
),
array(
'key' => 'material',
'value' => $material,
'compare' => '='
),
array(
'key' => 'brand',
'value' => $brand,
'compare' => '='
)
)
));
And this will work fine if every value get's set. But if only one of the select boxes is used, the other two values will be empty and the query will not return any posts. Is there any way to say "only use this array in the meta query if this value is set"?
You can check for definition of variable and add additional filtering if it exists
$query_args = array(
'post_type' => 'products',
'posts_per_page' => 6,
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'product_check',
'compare' => 'EXISTS',
),
),
);
if(isset($color) && $color) {
$query_args['meta_query'][] = array('key' => 'color', 'value' => $color, 'compare' => '=');
}
if(isset($material ) && $material ) {
$query_args['meta_query'][] = array('key' => 'material ', 'value' => $material , 'compare' => '=');
}
if(isset($brand ) && $brand ) {
$query_args['meta_query'][] = array('key' => 'brand ', 'value' => $brand , 'compare' => '=');
}
$query = new WP_Query($query_args);
Related
I am performing a WP_Query on a custom post type called "task" that has a field "stage". I need to get all of the posts with a "stage" >= the "stage" of another task. Problem is stage is a string value, so using >= operator in the meta query won't work.
Currently my hack is to create an array that contains string value of numbers $stage to 50, and query for posts who's stage is in that array. This will work for the time being as no stage is above 12, but not a very scalable or dynamic solution. I'm wondering if there is a better way to mutate a value recieved in WP_query before the operator is used on it?
$stage = get_field('stage', $task_id);
$future_tasks = array();
for ($i = intval($stage); $i <= intval($stage) + 50; $i++) {
array_push($future_tasks, strval($i));
}
$tasks_query_args = array(
'post_type' => array('task'),
'posts_per_page' => -1,
'order' => 'DESC',
'meta_query' => array(
'0' => array(
'key' => 'project',
'value' => $project_id,
'compare' => '=',
),
'1' => array(
'key' => 'stage',
'value' => $future_tasks,
'compare' => 'IN',
),
'relation' => 'AND',
),
);
Ideally the second parameter of the query would be something like:
'1' => array(
'key' => 'stage',
'value' => intval($stage),
'compare' => '>=',
),
But that won't work because value of the stage field is a string.
Wondering if there are any ideas about how to better achieve this?
Seems like, using numeric type could solve the problem:
$tasks_query_args = array(
'post_type' => array( 'task' ),
'posts_per_page' => - 1,
'order' => 'DESC',
'meta_query' => array(
'0' => array(
'key' => 'project',
'value' => intval( $project_id ),
'compare' => '=',
'type' => 'numeric',
),
'1' => array(
'key' => 'stage',
'value' => intval( $task_id ),
'compare' => '>=',
'type' => 'numeric',
),
'relation' => 'AND',
),
);
How can I show user and order them by 2 meta fields? For example I have user query
$args = array(
'role' => 'specialist',
'meta_key' => 'proffession',
'meta_value' => $term->ID,
'meta_compare' => '=',
'number' => 20,
'paged' => $paged,
);
$user_query = new WP_User_Query($args);
I want to sort this query by two meta_values, for example in PHP:
if(get_usermeta( $user_id, $meta_key = 'be_first' )>time() AND get_usermeta( $user_id, $meta_key = 'pro_date' )>time())
// show this users first ordered by be_first DESC, ordered by pro_date
if($pro_date>time()){
//show this users second ordered by pro_date desc
}
//show all other users
You can try this... I don't have your fields, so this is not tested. You can create a meta_query where your clauses are set to compare exists then use those to orderby.
$args = array(
'role' => 'specialist',
'number' => 20,
'paged' => $paged,
'meta_query' => array (
'relation' => 'AND',
array(
'key' => 'profession',
'value' => '$term->ID',
'compare' => '=',
),
'be_first_clause' => array(
'key' => 'be_first',
'compare' => 'EXISTS',
),
'pro_date_clause' => array(
'key' => 'pro_date',
'compare' => 'EXISTS',
),
),
'orderby' => array(
'be_first_clause' => 'ASC',
'pro_date_clause' => 'ASC'
)
);
$user_query = new WP_User_Query($args);
I want to query first and last name using custom post type metaboxes.
Code i am using:
$name = 'John Doe';
$args = array(
'post_type' => 'customers',
'post_status' => array( 'publish', 'pending', 'draft' ),
'numberposts' => -1,
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_key' => 'customer_first_name'
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'customer_first_name',
'value' => $name,
'compare' => 'LIKE',
),
array(
'key' => 'customer_last_name',
'value' => $name,
'compare' => 'LIKE',
),
),
);
$customers = get_posts($args);
$num = count( $customers );
If i search only "John" results are showing up. If i search full name "John Doe" there are no results. Why is that?
Of course it's show no result because you don't split the name first name and last name.
$name = 'John Doe';
$parts = explode(" ", $name);
$first_name = $parts[0];
$last_name = (count($name) > 1) ? $name[count($name)-1]: $first_name;
$args = array(
'post_type' => 'customers',
'post_status' => array( 'publish', 'pending', 'draft' ),
'numberposts' => -1,
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_key' => 'customer_first_name',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'customer_first_name',
'value' => $first_name,
'compare' => 'LIKE',
),
array(
'key' => 'customer_last_name',
'value' => $last_name,
'compare' => 'LIKE',
),
),
);
$customers = get_posts($args);
$num = count( $customers );
Like international name, if last name is blank then last name will use first name too.
I'm trying to list an archive of queried custom post types named 'jobs', each with a custom field of 'minimum_salary' and 'maximum_salary'.
On the previous search page the user enters two values in the search ('min-salary' & 'max-salary'), which are added to the URL of the archive page.
I want to be able to display ALL jobs that have a 'minimum_salary' AND 'maximum_salary' BETWEEN the min and max salary var the user entered on the previous page.
See below for my code so far, thanks for the help.
<?php
$minSalaryVar = get_query_var('min-salary');
$maxSalaryVar = get_query_var('max-salary');
$taxArgs = array();
if ($minSalaryVar && $maxSalaryVar) {
$taxArgs[] = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'minimum_salary',
'value' => array($minSalaryVar, $maxSalaryVar),
'compare' => 'BETWEEN',
'type' => 'numeric'
),
array(
'key' => 'maximum_salary',
'value' => array($minSalaryVar, $maxSalaryVar),
'compare' => 'BETWEEN',
'type' => 'numeric'
),
)
);
}
if ($taxArgs) {
$args = array (
'tax_query' => $taxArgs,
);
$argsNew = array_merge( $wp_query->query_vars, $args );
query_posts( $argsNew );
} ?>
You are using 'compare' = 'BETWEEN' two times when you need either using it just once or compare twice one greater than minimum salary and the other bigger. Following I'll let both options:
1:
if ($minSalaryVar && $maxSalaryVar) {
$meta_query = array(
'relation' => 'AND',
array(
'key' => 'minimum_salary',
'value' => $minSalaryVar,
'compare' => '>=',
'type' => 'numeric'
),
array(
'key' => 'maximum_salary',
'value' => $maxSalaryVar,
'compare' => '<=',
'type' => 'numeric'
),
);
}
if ($taxArgs) {
$args = array (
'meta_query' => $meta_query,
);
$argsNew = array_merge( $wp_query->query_vars, $args );
query_posts( $argsNew );
} ?>
2:
$taxArgs = array();
if ($minSalaryVar && $maxSalaryVar) {
$meta_query = array(
'key' => 'minimum_salary',
'value' => array($minSalaryVar,$maxSalaryVar),
'compare' => 'BETWEEN
'type' => 'numeric'
);
}
if ($taxArgs) {
$args = array (
'meta_query' => $meta_query,
);
$argsNew = array_merge( $wp_query->query_vars, $args );
query_posts( $argsNew );
} ?>
--- EDIT
You should use 'meta_query' instead of 'tax_query'
Im having trouble with my WordPress query on a project I do for a customer of us. Basically my problem is that I want to grab posts from the database with specified meta_keys. I want to get my posts (wpcompare) with the meta key '_price' and value between xx and yy. Works fine so far. Now I want to add filters for manufacturer, categories and tags. These filter values are all multiple, so that you can select multiple manufacturers. For example Canon and Nikon. So with the WP_MetaQuery I can filter multiple meta_keys and values, but I cant combine the queries with AND or OR.
Let me give you an example, how my query should work:
"Give me all the posts with post_type "wpcompare" where the meta_value _price is between 100 and 200 bucks, and where the manufacturer (_hersteller) is Canon OR Nikon OR Sony".
My head turns crazy, so please help me.
Thank you very much in advance :-)
Here is my Code:
if(isset($_POST) AND !empty($_POST))
{
$meta_query = array(
'relation' => 'AND',
array(
'key' => '_price',
'value' => array($_POST['p_from'], $_POST['p_to']),
'type' => 'CHAR',
'compare' => 'BETWEEN'
),
);
}
else
{
$meta_query = '';
}
$args = array(
'post_type' => 'wpcompare',
'post_status' => 'publish',
'paged' => $paged,
'meta_query' => $meta_query,
'posts_per_page' => ($per_page == false) ? 18 : $per_page,
'ignore_sticky_posts'=> true
);
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query($args)
$args = array(
'post_type' => 'posttypehere',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_price',
'value' => array($_POST['p_from'], $_POST['p_to']),
'type' => 'CHAR',
'compare' => 'BETWEEN'
),
array(
'key' => 'somekey',
'value' => array($_POST['p_from'], $_POST['p_to']),
'type' => 'CHAR',
'compare' => 'BETWEEN'
),
array(
'key' => 'anotherkey',
'value' => array($_POST['p_from'], $_POST['p_to']),
'type' => 'CHAR',
'compare' => 'BETWEEN'
),
)
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while ($query->have_posts()) : $query->the_post();
echo $post_id = get_the_ID();
endwhile;
endif;
$meta_query = array(
'relation' => 'OR',
array(
'key' => '_price',
'value' => array($_POST['p_from'], $_POST['p_to']),
'type' => 'CHAR',
'compare' => 'BETWEEN'
),
array(
'key' => 'somekey',
'value' => array($_POST['p_from'], $_POST['p_to']),
'type' => 'CHAR',
'compare' => 'BETWEEN'
),
array(
'key' => 'anotherkey',
'value' => array($_POST['p_from'], $_POST['p_to']),
'type' => 'CHAR',
'compare' => 'BETWEEN'
),
);