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.
Related
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.
I would like to retrieve all those posts whose author (post table field) is a given one OR those which has a given meta value (postmeda table field).
If "author" was a meta value, I know I could use a meta_query to achieve it. The thing here is that it is not... so I think I cannot use the "author" field within a meta_query and use the "relation" key.
I'm looking for something like:
$args = array(
'post_type' => array('post'),
'orderby' => 'ASC',
'order' => 'date',
'meta_query' => array(
'relation' => 'OR',
array(
'relation' => 'AND',
array(
'field' => 'author',
'value' => $author_id,
'compare' => '==',
),
array(
'key' => '_meta_field_name',
'compare' => 'NOT EXISTS',
),
),
array(
'relation' => 'AND',
array(
'key' => '_meta_field_name',
'compare' => 'EXISTS',
),
array(
'key' => '_meta_field_name',
'value' => $meta_field_value,
'compare' => '==',
),
),
),
);
$data = new WP_Query( $args );
Any suggestion on how to achieve that using WP_Query?
Thanks!
You might like to try an approach like this one instead. The idea is to query the two conditions you want to search for, then merge the two queries into one finished product.
//Get posts with the author you're looking for
$args1 = array(
'author_name' => 'testuser', //or 'author' => $author_id or something else
);
$data1 = get_posts( $args1 );
//Get posts with the meta data you're looking for
$args2 = array(
'meta_query' => array(
array(
'key' => 'meta_field_name',
'compare' => 'EXISTS',
),
array(
'key' => 'meta_field_name',
'value' => $meta_field_value,
'compare' => '==',
),
),
);
$data2 = get_posts( $args2 );
//Merge both arrays
$allData = array_merge( $data1, $data2 );
//Get just the IDs of all the posts found, while also dropping any duplicates
$postIDs = array_unique( wp_list_pluck( $allData, 'ID' ) );
//Do a new query with these IDs to get a properly sorted array of post objects
$args3 = array(
'post__in' => $postIDs,
'order' => 'ASC',
'orderby' => 'date',
);
$finalAnswer = get_posts( $args3 ); //This is your array of post objects. Ta-Da!
i'm facing wordpress meta_query problem, from this simple query i am not able to output values :
(
[post_type] => offres
[meta_query] => Array
(
[0] => Array
(
[key] => topics
[value] => Array
(
[0] => PADINE
[1] => ALKEKENGE
)
[compare] => IN
)
)
)
This is the php code :
$args = array(
'post_type' => 'offres',
'meta_query' => array(
array(
'key' => 'topics',
'value' => array('PADINE','ALKEKENGE'),
'compare' => 'IN'
)
)
);
On my wordpress admin i have a post assigned with 'topics' meta key and 'PADINE' as value, i wonder why is it not working ?
Thank you for your helps.
Sometimes, it is hard to get the meta value due to the serialize structure of the data.
$args = array(
'post_type' => 'offres',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'topics',
'value' => 'PADINE',
'compare' => 'LIKE',
),
array(
'key' => 'topics',
'value' => 'ALKEKENGE',
'compare' => 'LIKE',
)
)
);
Hope it works,
Thanks
I have a wordpress query that is not-using a meta key and needs to override the default AND to an OR
Code snippet:
$args = array(
'post_type' => 'post',
'author__in' => $follow_authors,
'tag_slug__in' => $follows
);
The output statement is ...WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (71) ) AND wp_posts.post_author IN (3)...
I can't find a way to make the ..) AND wp.posts.post_author... to be an OR
Something like this should get you started:
$meta_query_args = array(
'relation' => 'OR', // Optional, defaults to "AND"
array(
'key' => '_my_custom_key',
'value' => 'Value I am looking for',
'compare' => '='
)
);
$meta_query = new WP_Meta_Query( $meta_query_args );
There is more in-depth explanation and examples here: https://codex.wordpress.org/Class_Reference/WP_Meta_Query
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 '='.