Comparing arrays in WP_Query with custom fields - wordpress

I'm having an issue with comparing values between two arrays in wp_query
I have the two roles administrator and forhandler_salg ($roles returns an array with these two values), but it only queries posts with the "public" key set to true
I got more posts when I changed the "allowed_userroles" key compare value to "LIKE", but those aren't the right posts
$roles = "";
if (is_user_logged_in()) {
$user = wp_get_current_user();
$roles = (array) $user->roles;
}
$args = array(
'post_type' => 'downloads',
'posts_per_page' => '-1',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'public',
'value' => true,
'compare' => '=',
),
# Not working
array(
'key' => 'allowed_userroles',
'value' => $roles,
'compare' => 'IN',
),
),
);
print_r($args) returns
Array
(
[post_type] => downloads
[posts_per_page] => -1
[meta_query] => Array
(
[relation] => OR
[0] => Array
(
[key] => public
[value] => 1
[compare] => =
)
[1] => Array
(
[key] => allowed_userroles
[value] => Array
(
[16] => administrator
[17] => forhandler_salg
)
[compare] => IN
)
)
)
And a post with the "public" custom field as true and some added roles returns this, when I print_r() the allowed_userroles for the post:
Array
(
[0] => role1
[1] => role2
[2] => role3
)
How would I go about checking if allowed_userroles in the query has values that are also present in $roles?
EDIT: "like" works if I put in a role manually

Ok, for these kinds of problems, it's easier to start with your basic array of arguments and then modify it.
Since this question is tagged with ACF, ACF is likely storing this as a single meta entry. Furthermore, if this is an array of values, ACF is very likely storing it as a serialized PHP string in the database (e.g., a:2:{i:0;s:4:"1234";i:1;s:3:"qed";}).
Let's start with the base code:
$roles = [];
if (is_user_logged_in()) {
$user = wp_get_current_user();
$roles = (array) $user->roles;
}
$args = array(
'post_type' => 'downloads',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'public',
'value' => "1",
'compare' => '=',
),
),
);
In this case, you'll need to use a LIKE to attempt a sub-string match.
foreach($roles as $role) {
$args['meta_query'][] = [
'key' => 'allowed_userroles',
'value' => $role, // can't remember if wp will wrap value with %
'compare' => 'LIKE',
];
}
Ideally, you'd want to match based on the string length as well, but that might be a bit prohibitive. If you keep running into issues getting the exact results out, you could run two separate queries. The first query would be for all public items, and the second query would be for non-public items. You could then take the results of the second query and then filter out values that do not have the correct meta, since it'll be easier to process using get_field('allowed_userroles').

Related

WordPress get_users meta_query search object value

I'm running a query on users and want to include only users who have meta data (page_history) with a specific value. The problem I'm having is that the meta data is an object, and I can't seem to get the query to check the value of the object:
$role = isset($_GET['role'] && $_GET['role'] !== '');
$args = array(
'role' => $role ?? '',
'orderby' => 'user_nicename',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
$search_term[0] ? array(
'key' => 'first_name',
'value' => $search_term[0],
'compare' => 'LIKE'
) : '',
$search_term[1] ? array(
'key' => 'last_name',
'value' => $search_term[1],
'compare' => 'LIKE'
) : '',
array(
'key' => 'page_history',
'value' => 'custom_post_type',
'compare' => 'EXISTS'
)
),
);
$users = get_users($args);
foreach ($users as $user) {
// Do stuff
}
Here is my meta object:
Array
(
[date] => 1655387457
[post-type] => custom_post_type
[page] => Page title here
)
So I just want to get users if they have the meta data page_history set as 'custom_post_type'.
Thank you
This meta object will be serialized before being stored in the database column.
The post-type field after serialization will be like that in DB s:9:"post-type";s:16:"custom_post_type";
You can use LIKE compare to filter it.
array(
'key' => 'page_history',
'value' => 's:9:"post-type";s:16:"custom_post_type";',
'compare' => 'LIKE'
)
You will need to change the number 16 to the custom post type name count.

Wordpress meta_query meta_value an array of values when metadata to compare is serialized array?

I am trying to run a meta_query meta_value with an array of values and have it search if all are present in the meta value which is stored in a serialized array. Is this possible?
I want to get a query meta_value = array( post_id => 21583, select => 1 ) but stored in serialized array
a:3:{i:0;s:0:"";i:21583;a:3:{s:7:"post_id";s:5:"21583";s:6:"select";i:1;s:4:"date";s:19:"2020-12-22 09:01:39";}i:21120;a:3:{s:7:"post_id";s:5:"21120";s:6:"select";i:3;s:4:"date";s:19:"2020-12-22 09:02:02";}}
I want this serialized array value "post_id";s:5:"21583";s:6:"select";i:1;
Eg :
$args = array(
'post_type' => 'post',
'posts_per_page' => '9',
'meta_query' => array(
array(
'key' => 'users',
'value' => array(post_id => 21583, select => 1),
'compare' => '='
)
)
);

Woocommerce get order items of similar orders

In a plugin I'm trying to not letting users placing similar orders with same billing information.
Imagine a user with John Doe billing first name and last name has placed an order which contains product1 and product2 and someone else tries to place same or similar order (for example containing product1,product2, product3) with same billing first name and last name while the previous order is still under processing.
So in order to avoid this behavior I'm trying to validate orders before placement.
If there are any running orders with same billing info I throw a Woocommerce error but I don't know how can I make sure if last orders contain similar items too!
Here is my code:
function check_for_duplicate_order($data)
{
$data['billing_last_name'];
$data['billing_first_name'];
$data['billing_postcode'];
$meta_query_args = array(
'relation' => 'OR', // Optional, defaults to "AND"
array(
'key' => '_billing_postcode',
'value' => '%' . $data['_billing_postcode'],
'compare' => 'LIKE'
),
array(
'key' => '_billing_phone',
'value' => '%' . $data['billing_phone'],
'compare' => 'LIKE'
),
array(
'relation' => 'AND',
array(
'key' => '_billing_first_name',
'value' => $data['billing_first_name'],
'compare' => '='
),
array(
'key' => '_billing_last_name',
'value' => $data['billing_last_name'],
'compare' => '='
)
)
);
$query_params = [
'post_type' => 'shop_order',
'posts_per_page' => 1,
'post_status' => array('wc-pending','wc-processing','wc-on-hold'),
'meta_query' => $meta_query_args
];
$cart_items_ids = [];
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$cart_items_ids[] = $values['data']->get_id();
}
}
add_action('woocommerce_after_checkout_validation', 'check_for_duplicate_order');
In above code I get current order billing info, then finding other active orders with same billing info but from this point I don't know How can get found orders items and see if in previous orders there are same items too.
I managed to find a solution to match items in current cart with items in previous orders :
foreach ($billing_active_order_ids as $active_order_id){
$order = wc_get_order( $active_order_id );
foreach ($order->get_items() as $id => $order_item){
if(in_array($order_item->get_product_id(),$cart_items_ids)){
wc_add_notice($duplicate_order_message, 'error');
return;
}
}
}

Is there an way 'We pass $_Get values into an array'

I am getting url string,
product_cat=booking&min_prep_time=180&max_prep_time=220
and i am passing the values into array with help of $_GET. Recently i modified the code in my custom file for tax_query and meta_query, these work fine for me but according to my custom requirement i changed the static values into dynamic variable seems like this
when i used the static value the array is perfectly working and fetched perfect data
Before Array with static values was working
$meta_query[] = array(
'key' => '_new_field',
*'value' => array( '19','22'),*
'compare' => 'between',
);
After Its not working
$meta_query[] = array(
'key' => '_new_field',
*'value' => array( $min,$max),*
'compare' => 'between',
);
This is my complete code i am sure this will help you to understand my problem
$prod = isset($_GET['product_cat']) ? $_GET['product_cat'] : FALSE;
$min = isset($_GET['min_prep_time']) ? $_GET['min_prep_time'] : FALSE;
$max = isset($_GET['max_prep_time']) ? $_GET['max_prep_time'] : FALSE;
if( $prod && ($prod=="booking") && $min && $max) {
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( $prod ), // Don't display products in the clothing category on the shop page.
'operator' => 'IN'
);
$meta_query = (array)$q->get('meta_query');
// Add your criteria
$meta_query[] = array(
'key' => '_new_field',
'value' => array( $min,$max),
'compare' => 'between',
);
// Set the meta query to the complete, altered query
$q->set('meta_query',$meta_query);
$q->set('tax_query', $tax_query);
What i want
i just want i passed the values that i get from url and array will perfectly working as it work for static values.
many thanks

Multiple custom field sorting on wordpress archive page

I have been through several topics on sorting taxonomies and custom fields, including some that were promising. However, I am still not constructing my query args correctly it seems.
I am "fixing" someone else's code in a custom theme that is used in a multisite configuration, but I am able to override/filter the query on a per-site basis.
The query is called via the theme with the following:
return apply_filters( 'theme_query_args_filter', $args);
I have custom fields in the "role" taxonomy that include:
last_name
first_name
Pretty common I think.
However, when the args are executed, the following filter args are sorting only by last name (key part is the else clause):
function my_args_filter( $args ) {
if (is_home() && !is_search()) {
$args['meta_key'] = 'event_date';
$args['orderby'] = 'event_date';
$args['order'] = 'DESC';
}
else {
$tax = $args['taxonomy'];
$theterm = $args['term'];
$args = array (
'taxonomy' => $tax,
'term' => $theterm,
'meta_key' => 'last_name',
'orderby' => 'meta_value',
'order' => 'ASC'
);
}
add_filter( 'theme_query_args_filter', 'my_args_filter' );
I've tried to modify the orderby as indicated in https://make.wordpress.org/core/2014/08/29/a-more-powerful-order-by-in-wordpress-4-0/ to use an array to do a multisort, but I'm hitting my head up against the wall. I think the problem is that the code is written using a mixture of old ways of doing things and new ways.
Any advice is appreciated. According to the example on in the docs above, I SHOULD be able to pass in multiple meta key/value/orders via an array, but I'm just not getting it.
Thanks for any leads you might have. (long-time listener, first-time caller)
(I also looked at https://wordpress.stackexchange.com/questions/109849/order-by-desc-asc-in-custom-wp-query but I couldn't extrapolate that example to this one either)
Figured it out on my most recent try. Hat tip to this solution https://wordpress.stackexchange.com/questions/249881/multiple-custom-fields-for-orderby-in-wp-query by Nath. if there is a more elegant way to do it, please let me know.
$tax = $args['taxonomy'];
$theterm = $args['term'];
$paged = $args['paged'];
$args = array (
'taxonomy' => $tax,
'term' => $theterm,
'paged' => $paged,
'posts_per_page' => '10',
'meta_query' => array(
array(
'relation' => 'AND',
'last_name' =>
array(
'key' => 'last_name',
'compare' => 'EXISTS',
),
'first_name' =>
array(
'key' => 'first_name',
'compare' => 'EXISTS',
),
),
),
'orderby' => array (
'last_name' => 'ASC',
'first_name' => 'ASC',
)
);
}

Resources