Wordpress, multiple meta_key in pre_get_posts - wordpress

is it possible to add two meta_key's in pre_get_posts?
my current query
$query->set('s', '' );
$query->set( 'meta_key', 'cat_adresse_stadtteil' );
$query->set( 'meta_value', array('charlottenburg', 'wilmersdorf', 'schmargendorf') );
add this
$query->set('orderby','meta_value_num');
$query->set('meta_key', 'rank');
$query->set('order', 'ASC');
EDIT
Ok, i found this solution (link #example 2)
$args = array(
'numberposts' => -1,
'post_type' => 'event',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'location',
'value' => 'Melbourne',
'compare' => '='
),
array(
'key' => 'attendees',
'value' => 100,
'type' => 'NUMERIC',
'compare' => '>'
)
)
);
but it doesnt work, any ideas what is wrong?
$query->set('meta_query',array(
array( 'key' => 'cat_adresse_stadtteil',
'value' => array('charlottenburg', 'wilmersdorf', 'schmargendorf'), ),
array( 'key' => 'rank'
'orderby' => 'meta_value_num',
'order' => 'ASC' ) ) );

To combine the two parts, you can try the following:
add_action( 'pre_get_posts', function( $q ) {
// Only modify the main query on the front-end:
if( ! is_admin() && $q->is_main_query() )
{
$meta_query = array(
array(
'key' => 'cat_adresse_stadtteil',
'value' => array('charlottenburg', 'wilmersdorf', 'schmargendorf'),
'compare' => 'IN',
),
);
$q->set( 'meta_query', $meta_query );
$q->set( 'meta_key', 'rank' );
$q->set( 'orderby', 'meta_value_num' );
$q->set( 'order', 'ASC' );
$q->set( 's', '' );
}
});
It looks like you were missing the compare parameter and using the order and orderby parameters in a wrong place. I'm not sure though why you are resetting the search parameter.
The generated SQL query will look something like:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_postmeta
ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1
ON (wp_posts.ID = mt1.post_id)
WHERE 1=1
AND wp_posts.post_type
IN ('post', 'page', 'attachment' )
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_author = 1
AND wp_posts.post_status = 'private')
AND (wp_postmeta.meta_key = 'rank'
AND (mt1.meta_key = 'cat_adresse_stadtteil'
AND CAST(mt1.meta_value AS CHAR)
IN ('charlottenburg','wilmersdorf','schmargendorf')) )
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value+0 ASC
LIMIT 0, 10

You can convert this query to pre_pget_posts:
$meta_query_args = array(
'relation' => 'AND', // "OR"
array(
'key' => '_my_custom_key',
'value' => 'Value I am looking for',
'compare' => '='
),
array(
'key' => '_your_min_model_key',
'value' => 1453,
'compare' => '>'
),
array(
'key' => '_your_max_model_key',
'value' => 1923,
'compare' => '<'
)
);
$meta_query = new WP_Meta_Query( $meta_query_args );
And compare param details:
compare (string) - Operator to test. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS' (only in WP >= 3.5), and 'NOT EXISTS' (also only in WP >= 3.5). Values 'REGEXP', 'NOT REGEXP' and 'RLIKE' were added in WordPress 3.7. Default value is '='.

Related

Wooocommerce order "on-sale first" products inside shop and archives

i need to alter the default woocommerce filter by setting up the "on sale" products as first. The loop must contain also the not on sale, but all is ordered by on sale first.
I tried using pre_get_posts but i find the way only to filter the products (for ex display only the on sale product), not reorder it.
I solved the problem, here the solution, hope is useful for other people.
/**
* #param $q
* Reorder products on sale first on default shop filter.
*
* #return void
*/
function evolve_on_sale_reorder_query( $q ) {
$meta_query = $q->get( 'meta_query' );
if ( ! isset( $_GET['orderby'] ) ) {
$meta_query = array(
'relation' => 'OR',
array(
'key' => '_sale_price',
'compare' => 'NOT EXISTS'
),
array(
'relation' => 'OR',
array(
'key' => '_sale_price',
'value' => '',
'compare' => "="
// 'value'=>array(''),
// 'compare' => 'IN'
),
array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>=',
'type' => 'numeric',
)
),
);
$q->set( 'orderby', array( 'meta_value' => 'DESC', 'title' => 'ASC' ) );
}
$q->set( 'meta_query', $meta_query );
}
add_action( 'woocommerce_product_query', 'evolve_on_sale_reorder_query' );

Why get_posts() return empty data?

I'm trying to get posts of some type matching a meta query, but whatever I try, I get empty results.
I have
$meta_query = array(
'relation' => 'OR',
array(
'key' => '_wpm_gtin_code',
'compare' => 'EXISTS'
),
array(
'key' => '_product_code',
'compare' => 'EXISTS'
)
);
$args = array(
'meta_query' => $meta_query,
'post_type' => 'product',
'post_status' => 'publish'
//'posts_per_page' => -1
);
error_log(print_r($args, true));
$posts = get_posts( $args );
error_log(print_r($posts, true));
and I see in log file
[02-Mar-2020 06:51:12 UTC] Array
(
[meta_query] => Array
(
[relation] => OR
[0] => Array
(
[key] => _wpm_gtin_code
[compare] => EXISTS
)
[1] => Array
(
[key] => _product_code
[compare] => EXISTS
)
)
[post_type] => product
[post_status] => publish
)
[02-Mar-2020 06:51:12 UTC] Array
(
)
When I select the data manually with this SQL query:
SELECT * FROM wp_posts
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE wp_posts.post_type = 'product' AND wp_posts.post_status = 'publish' AND
(wp_postmeta.meta_key = '_wpm_gtin_code' OR wp_postmeta.meta_key = '_product_code')
I get correct result of two rows.
What am I doing wrong?
$meta_query = array(
'relation' => 'OR',
array(
'key' => '_wpm_gtin_code',
'compare' => 'EXISTS',
'value' => '' // This is ignored, but is necessary...
),
array(
'key' => '_product_code',
'compare' => 'EXISTS',
'value' => '' // This is ignored, but is necessary...
)
);
$args = array(
'meta_query' => $meta_query,
'post_type' => 'product',
'post_status' => 'publish',
//'posts_per_page' => -1
);
try adding 'value' => '' in array ...
I dived into WP code to find out that the query contained tax_query even I didn't pass any to my get_post() call. So I searched where the query got altered and found that the whole problem was in WooCommerceCategoryExcluder plugin which hooked to pre_get_posts and added taxonomy query to my get_posts() args.
Maybe this investigation helps someone else trying to solve similar problem.

Wordpress: search users using 'first_name' and 'last_name'?

UPDATE: I mean to search user in the Admin User Dashboard at /wp-admin/users.php
Is there a way to search users using 'first_name' and 'last_name'?
I found this plugin but not working at all: https://wordpress.org/plugins/full-name-search-in-wp-admin/
I also found this function, but neither is working in my site. Do I need to call the function with a hook/action?:
function search_users($search_term){
global $wpdb;
$the_users = $wpdb->get_results("SELECT DISTINCT $wpdb->users.* FROM $wpdb->users INNER JOIN $wpdb->usermeta um1 ON um1.user_id = $wpdb->users.ID JOIN $wpdb->usermeta um2 ON um2.user_id = $wpdb->users.ID WHERE (um1.meta_key = 'uRPhICRS_capabilities' AND um1.meta_value LIKE '%agent%') AND ((um2.meta_key = 'first_name' OR um2.meta_key = 'last_name') AND um2.meta_value LIKE '%".$search_term."%');");
if(!empty($the_users)){
return $the_users;
}
else{
return false;
}
}
Two Ways as follow:
1) If You want to check from the string match in either firstname or lastname, following will be work:
$users_query = new WP_User_Query(
array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'first_name',
'value' => $str,
'compare' => 'LIKE'
),
array(
'key' => 'last_name',
'value' => $str,
'compare' => 'LIKE'
)
)
)
);
$users = $users_query->get_results();
2) If you want to check the user from username, user_nicename, user_email, firstname, or lastname use following code:
//search from the user table
$users_query_table = new WP_User_Query(
array(
'search' => "*{$str}*",
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
),
) );
$users_via_table = $users_query_table->get_results();
//search from the usermeta
$users_query_meta = new WP_User_Query(
array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'first_name',
'value' => $str,
'compare' => 'LIKE'
),
array(
'key' => 'last_name',
'value' => $str,
'compare' => 'LIKE'
)
)
)
);
$users_via_meta = $users_query_meta->get_results();
// Merge both result..
$combined_users = array_merge( $users_via_table, $users_via_meta );
// Get unique user
$users = array_unique( $combined_users, SORT_REGULAR );
You can use WP_User_Query.
Example:
// The search term
$search_term = 'Ross';
// WP_User_Query arguments
$args = array (
'role' => 'reporter',
'order' => 'ASC',
'orderby' => 'display_name',
'search' => '*'.esc_attr( $search_term ).'*',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'first_name',
'value' => $search_term,
'compare' => 'LIKE'
),
array(
'key' => 'last_name',
'value' => $search_term,
'compare' => 'LIKE'
),
array(
'key' => 'description',
'value' => $search_term ,
'compare' => 'LIKE'
)
)
);
// Create the WP_User_Query object
$wp_user_query = new WP_User_Query($args);
https://developer.wordpress.org/reference/classes/wp_user_query/

How to order posts list using wp_query?

I want to order my list with wp_query. I have posts with meta_key 'featured_post' and three values for that key for different posts it is: '1', '2', and thrird key not exist.
I am using now this wp_query structure:
global $paged, $wp_query, $wp;
$args = wp_parse_args($wp->matched_query);
if ( !empty ( $args['paged'] ) && 0 == $paged ) {
$wp_query->set('paged', $args['paged']);
$paged = $args['paged'];
}
$temp = $wp_query;
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 20,
'paged' => $paged,
'meta_query' => array(
'relation' => 'OR',
'featured_clause_first' => array(
'key' => 'featured_post',
'value' => '1',
'compare' => '='
),
'featured_clause_second' => array(
'key' => 'featured_post',
'value' => '2',
'compare' => '='
),
'featured_clause_third' => array(
'key' => 'featured_post',
'compare' => 'NOT EXISTS',
'value' => '1'
)
),
'orderby' => array(
'featured_clause_first' => 'DESC',
'featured_clause_second' => 'DESC',
'featured_clause_third' => 'DESC'
),
);
$wp_query = null;
$wp_query = new WP_Query($args);
while ($wp_query->have_posts()) : $wp_query->the_post();
get_template_part( 'templates/single');
endwhile;
wp_reset_postdata();
wp_reset_query();
But I am got wrong order. Finally I need to see posts with value '1' at the top and other posts with values '2' and not exist key after.
Note: I can't use "'meta_key' => 'featured_post'," because in this way posts without existing meta_key not displayed.
Ok. I was edited save metabox functions for delete metakey if featured not checked. So that I have only two values: 1 & key not exist. After that I got needed order with this meta args:
$sort_meta_query = array(
'relation' => 'OR',
'featured_clause' => array(
'key' => 'featured_post',
'value' => '1',
'compare' => '='
),
array(
'key' => 'featured_post',
'compare' => 'NOT EXISTS',
'value' => '1'
)
);
$sort = array(
'orderby' => array(
'featured_clause' => 'DESC',
'date' => 'DESC'
)
);

Get all wp_users sort by metakey

I am trying to get users list sort by metakey. I mean i have set meta key user_last_login. some users doesnot have this meta key. some users have it.
I want to get both users in single query but if metakey exists those will come first and remaining should come last.
Here is my query
$meta_query_args = array(
'relation' => 'OR', // Optional, defaults to "AND"
array(
'key' => 'user_last_login',
'compare' => 'Not Exists'
),
array(
'key' => 'user_last_login',
'compare' => 'Exists'
)
);
$meta_query = new WP_Meta_Query( $meta_query_args );
$args = array(
'offset' => $paged ? ($paged - 1) * $number : 0,
'number' => $number,
'fields' => 'all',
'orderby'=>'user_last_login',
'exclude' => array(get_current_user_id()),
'meta_query' =>$meta_query
);
$users = get_users( $args );
Please help.
A meta_key argument is required when you wan to order by meta_value. Here is the modified code,
$query_args = array(
'relation' => 'OR',
array(
'key' => 'user_last_login',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'user_last_login',
'compare' => 'EXISTS'
)
);
$meta_query = new WP_Meta_Query($query_args);
$args = array(
'offset' => $paged ? ($paged - 1) * $number : 0,
'number' => $number,
'fields' => 'all',
'meta_key' => 'user_last_login',
'orderby' => 'meta_value',
'order' => 'ASC',
'exclude' => array(get_current_user_id()),
'meta_query' => $meta_query
);
$users = get_users( $args );
Hope this one helps.

Resources