ACF Query Posts by Repeater Field Not Empty - wordpress

This question seems to be unanswered on the internet, perhaps because it is not possible. I simply want to query all posts where the repeater field 'has rows'. i.e.
$args = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'repeater_field',
'value' => '',
'compare' => '=!'
)
);
I know an alternative is to run if statements inside the loop to filter them out, but that messes with some other logic which is based off of the number of posts in the query.
Does anyone have any thoughts on this?

Let's consider you have a Repeater Field labeled My Repeater Field and this repeater contains at least one field labeled A Field on the Repeater.
Assuming you have the default wp_ table prefix, you need to look at the DB's wp_postmeta table to notice that values for this field on the repeater are stored with the meta_key:
NAME_OF_THE_REPEATER_index_NAME_OF_FIELD_ON_THE_REPEATER
So, in our case, if a post has 3 rows on the repeater field, its values will be stored as:
my_repeater_field_0_a_field_on_the_repeater
my_repeater_field_1_a_field_on_the_repeater
my_repeater_field_2_a_field_on_the_repeater
Knowing this, if you want to query all posts having at least ONE row on the repeater, you could do:
$meta_query = [
[
'key' => 'my_repeater_field_0_a_field_on_the_repeater',
'compare' => 'EXISTS',
]
];
$args = [
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => $meta_query,
'post_type' => 'post',
'post_status' => 'publish',
];
$posts_array = get_posts( $args );
Note: As stated on WP Docs, you can only use the EXISTS comparison on WP >= 3.5 and you don't need to specify a value when using the 'EXISTS' or 'NOT EXISTS' comparisons in WordPress 3.9 and up. I'm also assuming you are using PHP >= 5.4 so you can use short array syntax. If not, just replace [] for array().

You can query the wordpress database using the $wpdb object. ACF fields are saved in prod_postmeta on the database so that is where you will run your query. Your meta_value will be the key of your repeater field, so make sure you replace that in the query below. All keys for any ACF field with start out with field_ and then random characters/digits will follow like seen below. Then once you have the post id, you can run get_post() on those post ids. Let me know if you need anything else or have questions.
global $wpdb;
$results = $wpdb->get_results("SELECT post_id from prod_postmeta WHERE meta_value = 'field_534eeaaa74199'");
$echo $results;

This works. I have test it. Only by the "Welcome World" post it doesn't work.
$args = array(
'post_type'=> 'post',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'repeater_field',
'value' => '0',
'compare' => '!='
)
));
$the_query = new WP_Query( $args );
The "repeater_field" is the name of the field, not the field_key. Here is the count of the rows.

Related

WordPress custom query by meta_key

I'm trying to figure out how to achieve a specific query to modify my search results for posts with WordPress. I'm trying to search via a custom field called "Common Authors".
There can be multiple Common authors, which is causing my query to sometimes fail. Here is what I've got for now:
<?php
...
$query->set('meta_key', 'common_authors');
$query->set('meta_value', serialize( array(strval($_GET['common_author'])))); // I get a single ID from the url as a string
$query->set('meta_compare', 'IN');
This is what I see when I var_dump the query:
'meta_key' => string 'common_authors'
'meta_value' => string 'a:1:{i:0;s:5:"17145";}'
This works fine if there is only one common_author.
However, there can be multiple common_authors for a post. Here is a meta_value example from the database:
a:4:{i:0;s:5:"14409";i:1;s:5:"17145";i:2;s:5:"14407";i:3;s:5:"14406";}
Could somebody help me out, to figure out how to adapt my query, so that it would return this one as well?
Try This One Work Prefect!
$args = array(
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'common_authors',
'value' => array ( 'author1', 'author2', 'author3' ),
'compare' => 'IN'
)
)
);
$query = new WP_QUERY($args);
if You Need To Use It In pre_get_posts
$meta_query = array(
array(
'key' => 'common_authors',
'value' => array ( 'author1', 'author2', 'author3' ),
'compare' => 'IN'
)
);
$query->set('meta_query', $meta_query);

Get Posts based on serialized meta value

I have a series of posts and all have a meta_key with the value of "owner" and meta_value with serialized data such as "a:3:{i:0;s:3:"325";i:1;s:2:"41";i:2;s:2:"29";}"
meta_key owner
meta_value a:3:{i:0;s:3:"325";i:1;s:2:"41";i:2;s:2:"29";}
I am trying to figure out how to properly use get_posts() to return all the posts that have a meta_key with the value of owner and the meta_value containing a specific value such as 41
$args = array(
'post_type' => 'rp_applications',
'nopaging' => true,
'meta_query' => array(
'relation' => 'AND',
array(
'compare' => '=',
'key' => 'archived',
'value' => '0000-00-00'
),
array(
'compare' => '=',
'key' => 'owner',
'value' => ???? WHAT DO I PUT HERE ????
)
)
);
$applications = get_posts($args);
This sounds like you should be storing the "Owner" as a taxonomy term instead of meta data. It would give you easier and faster querying abilities as well.
That said, it's definitely possible to do what you want. I'd be cautious though, because the postmeta table by default is not indexed, so a large table with meta queries run against it will slow down your site quite a lot. You may want to consider adding a partial index to the table if it's going to be even remotely large (or again, switch to Taxonomy Terms instead of post meta for this).
If you still care to use a meta query, take a look at the compare options available in the WP_Meta_Query() docs.
One of the available options is REGEXP, so you could do something like:
$args = array(
'post_type' => 'rp_applications',
'nopaging' => true,
'meta_query' => array(
'relation' => 'AND',
array(
'compare' => 'REGEXP',
'key' => 'owner',
'value' => sprintf( 'a:\d:{i:0;s:\d:"\d.*?";i:1;s:%d:"%d".*', strlen($owner_id), $owner_id )
),
array(
'compare' => '=',
'key' => 'archived',
'value' => '0000-00-00'
)
)
);
Of course this method only works if the serialized data is in the same format on each one, and you'd need to adjust the regular expression if not - but that should be enough to get you started!

How to link custom field to shortcode?

I'm trying to link a custom field to a custom shortcode so the shortcode shows displays only the posts with the custom field selected to it.
This is my code below for my shortcode as you can see the key is my custom felid "flash_deal". When I enter the shortcode I just get all the perk psots and no the custom field perk posts?
add_shortcode('foundry_flash', 'shortcode_query_flash');
function shortcode_query_flash($atts, $content){
extract(shortcode_atts(array( // a few default values
'post_type' => 'perks',
'posts_per_page' => -1 ,
'meta_query' => array(
array(
'key' => 'flash_deal', // name of custom field
'value' => '"yes"', // matches exactly "red"
'compare' => 'LIKE'
)
)
), $atts));
The code you show is simply setting up variables - not running any queries at all (see extract documentation & shortcode_atts documentation).
I assume you have more code you just didn't add here, so likely the problem is the double quotes around yes that are causing issues. It's literally looking for "quoteyesquote".
As a general working example to get "Parks" Post based on custom meta, you need to use WP_Query as in the docs here.
$args = array(
'post_type' => 'parks',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'flash_deal',
'value' => 'yes',
'compare' => 'LIKE',
),
),
);
$query = new WP_Query( $args );
Then use a Nested Loop setup to loop through the results.

Wordpress Query on custom fields

My site has woocommerce plugin, so post_type is product. Each product has several custom fields used by another plugin (Compare Products Pro).
Now we would like to query products by URL so eg: www.domain.com/?post_type=product&custom_field=value
Is this possible? And how?
Any help would be highly appriciated!
You could add something like this to your query arguments:
'post_type' => $_GET['post_type'],
'meta_query' => array(
array(
'key' => '_woo_compare_field-',
'value' => $_GET['_woo_compare_field-'],
'compare' => '=',
)
),
But its very static, will not work for different meta key value pairs.
You could assign them to an array and append that array like this
$meta_queries = array(
'relation' => 'AND',
);
foreach($_GET as $key => $value) {
$result = array(
'key' => $key,
'value' => $value,
'compare' => '=',
);
$meta_queries[] = $result;
}
And append the $meta_queries array to the wordpress query arguments.
But this means all your get variables are used as meta key value pairs. You can ofcourse write some logic for this but it will never be pretty

WordPress: one condition for multiple values but one key when querying with custom fields

I am working on some kind of booking extension for a custom post type in Wordpress. The admin can choose the dates when the object is booked. The booked date is saved as a new custom field with the key "booking" and the date in the format "yymmdd". So one object can have multiple custom fields with the same key, but multiple values.
Now I need to query the objects that are available for a specific date. The following is one of my last attempts.
$args = array(
'post_type' => 'object',
'meta_query' => array(
array(
'key' => 'booking',
'value' => array('131020', '131021', '131022'),
'compare' => 'NOT IN'
)
)
);
$query = new WP_Query( $args );
From my logic, I am searching for an object that is available from 131020 to 131022. What WordPress sees to do though is comparing each of the available multiple values individually. So if the element is booked on 131019 and on 131020, WordPress still returns it as available, because 131019 is not in the values above.
What I need is a logic that say "if none of the multiple values is among the mentioned numbers, return the post"
I also tried using just a serialized array for all of the dates, but this didn’t work either. I am sure there might be a simple trick, but after doing a lot of research I am stuck here.
Any ideas?
Thanks
After many other approaches, I finally ended up with the following "solution".
I saved all the dates as an array and was using NOT LIKE for each of the dates that needed to be available. The code from above would look like this:
$args = array(
'post_type' => 'object',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'booking',
'value' => '131020',
'compare' => 'NOT LIKE'
),
array(
'key' => 'booking',
'value' => '131021',
'compare' => 'NOT IN'
),
array(
'key' => 'booking',
'value' => '131022',
'compare' => 'NOT IN'
)
)
);
$query = new WP_Query( $args );
Note relation => 'AND' at the beginning. As I understand, this is the default, but in case you use 'OR' here this wouldn’t work either.
Still happy about any comment on both of the approaches.

Resources