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
CodePudding user response:
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')
.