Ended up replacing the custom checkbox field with another custom taxonomy.
Another update… Turns out that the database can’t find any posts using the code examples from the documentation and it’s not possible to use the IN operator for checkboxes. I could only find results with the following SQL:
SELECT * FROM cms_posts INNER JOIN cms_postmeta ON( cms_posts.ID = cms_postmeta.post_id ) WHERE 1 = 1 AND( ( cms_postmeta.meta_key = 'pb_region' AND cms_postmeta.meta_value LIKE '%eu%' ) ) GROUP BY cms_posts.ID ORDER BY cms_posts.post_title ASC;
And the posts get filtered only if I set custom arguments in the template itself and manually setting the meta_query but not when using pre_get_posts
(I already checked if there was another instance overriding it, there isn’t).
This is the query when looping through a custom query and meta_query
defined with a string value:
WP_Query Object
(
[query] => Array
(
[post_type] => products
[orderby] => title
[order] => ASC
[posts_per_page] => -1
[tax_query] => Array
(
[taxonomy] => games
[term] => totk
)
[meta_query] => Array
(
[0] => Array
(
[key] => pb_region
[value] => eu
[compare] => LIKE
)
)
)
[query_vars] => Array
(
[post_type] => products
[orderby] => title
[order] => ASC
[posts_per_page] => -1
[tax_query] => Array
(
[taxonomy] => games
[term] => totk
)
[meta_query] => Array
(
[0] => Array
(
[key] => pb_region
[value] => eu
[compare] => LIKE
)
)
[...]
)
[...]
[meta_query] => WP_Meta_Query Object
(
[queries] => Array
(
[0] => Array
(
[key] => pb_region
[value] => eu
[compare] => LIKE
)
[relation] => OR
)
[relation] => AND
[meta_table] => cms_postmeta
[meta_id_column] => post_id
[primary_table] => cms_posts
[primary_id_column] => ID
[table_aliases:protected] => Array
(
[0] => cms_postmeta
)
[clauses:protected] => Array
(
[cms_postmeta] => Array
(
[key] => pb_region
[value] => eu
[compare] => LIKE
[compare_key] => =
[alias] => cms_postmeta
[cast] => CHAR
)
)
[has_or_relation:protected] =>
)
[...]
This is my current code, by the way:
$meta_query = array(
'key' => $name,
'value' => $value,
'compare' => 'LIKE'
);
Any input would be much appreciated.
(my reply got deleted somehow after editing so I’m reposting…)
I did some more debugging and noticed that meta_query
is getting populated (inside query_vars
) but it still doesn’t filter the posts. The loop remains unaffected and all posts are being displayed on both the taxonomy page and custom post type archive instead of getting filtered by the custom field pb_region => region
.
Here’s what $query
outputs currently on the taxonomy page after setting meta_query
:
WP_Query Object
(
[query] => Array
(
[games] => totk
)
[query_vars] => Array
(
[games] => totk
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[pagename] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[meta_key] =>
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[title] =>
[fields] =>
[menu_order] =>
[embed] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[post_name__in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
[post_parent__in] => Array
(
)
[post_parent__not_in] => Array
(
)
[author__in] => Array
(
)
[author__not_in] => Array
(
)
[search_columns] => Array
(
)
[meta_query] => Array
(
[key] => region
[value] => Array
(
[0] => eu
[1] => na
)
[compare] => IN
)
)
[tax_query] => WP_Tax_Query Object
(
[queries] => Array
(
[0] => Array
(
[taxonomy] => games
[terms] => Array
(
[0] => totk
)
[field] => slug
[operator] => IN
[include_children] => 1
)
)
[relation] => AND
[table_aliases:protected] => Array
(
)
[queried_terms] => Array
(
[games] => Array
(
[terms] => Array
(
[0] => totk
)
[field] => slug
)
)
[primary_table] =>
[primary_id_column] =>
)
[meta_query] =>
[date_query] =>
[post_count] => 0
[current_post] => -1
[in_the_loop] =>
[comment_count] => 0
[current_comment] => -1
[found_posts] => 0
[max_num_pages] => 0
[max_num_comment_pages] => 0
[is_single] =>
[is_preview] =>
[is_page] =>
[is_archive] => 1
[is_date] =>
[is_year] =>
[is_month] =>
[is_day] =>
[is_time] =>
[is_author] =>
[is_category] =>
[is_tag] =>
[is_tax] => 1
[is_search] =>
[is_feed] =>
[is_comment_feed] =>
[is_trackback] =>
[is_home] =>
[is_privacy_policy] =>
[is_404] =>
[is_embed] =>
[is_paged] =>
[is_admin] =>
[is_attachment] =>
[is_singular] =>
[is_robots] =>
[is_favicon] =>
[is_posts_page] =>
[is_post_type_archive] =>
[...]
)
And this is the template (just excluding the header and footer):
<?php $term = get_queried_object(); ?>
<?php if ( have_posts() ) : ?>
<div class="container">
<div id="primary" class="content products">
<div class="filters">
<?php foreach( $GLOBALS['query_filters'] as $key => $name ):
// get the field's settings without attempting to load a value
$field = get_field_object($key, false, false);
// set value if available
if( isset($_GET[ $name ]) ) {
$field['value'] = explode(',', $_GET[ $name ]);
}
// create filter
?>
<div class="filter" data-filter="<?php echo $name; ?>">
<?php create_field( $field ); ?>
</div>
<?php endforeach; ?>
<input type="hidden" class="js-filter-url" value="<?php echo home_url('products/' . $term->slug . '/'); ?>" />
</div>
</div>
<div class="product-grid">
<?php
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/post/content', 'product' );
endwhile; ?>
</div>
</div>
<?php else : ?>
<div class="container-s">
<div id="primary" class="content">
<?php get_template_part( 'template-parts/post/content', 'none' ); ?>
</div>
</div>
<?php endif; ?>
This is what $query
outputs on the custom post type archive:
WP_Query Object
(
[query] => Array
(
[post_type] => products
)
[query_vars] => Array
(
[post_type] => products
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[pagename] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[meta_key] =>
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[title] =>
[fields] =>
[menu_order] =>
[embed] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[post_name__in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
[post_parent__in] => Array
(
)
[post_parent__not_in] => Array
(
)
[author__in] => Array
(
)
[author__not_in] => Array
(
)
[search_columns] => Array
(
)
[meta_query] => Array
(
[key] => region
[value] => Array
(
[0] => as
)
[compare] => IN
)
)
[tax_query] => WP_Tax_Query Object
(
[queries] => Array
(
)
[relation] => AND
[table_aliases:protected] => Array
(
)
[queried_terms] => Array
(
)
[primary_table] =>
[primary_id_column] =>
)
[meta_query] =>
[date_query] =>
[post_count] => 0
[current_post] => -1
[in_the_loop] =>
[comment_count] => 0
[current_comment] => -1
[found_posts] => 0
[max_num_pages] => 0
[max_num_comment_pages] => 0
[is_single] =>
[is_preview] =>
[is_page] =>
[is_archive] => 1
[is_date] =>
[is_year] =>
[is_month] =>
[is_day] =>
[is_time] =>
[is_author] =>
[is_category] =>
[is_tag] =>
[is_tax] =>
[is_search] =>
[is_feed] =>
[is_comment_feed] =>
[is_trackback] =>
[is_home] =>
[is_privacy_policy] =>
[is_404] =>
[is_embed] =>
[is_paged] =>
[is_admin] =>
[is_attachment] =>
[is_singular] =>
[is_robots] =>
[is_favicon] =>
[is_posts_page] =>
[is_post_type_archive] => 1
[...]
)
And the template:
<?php if ( have_posts() ) : ?>
<div class="container">
<div class="filters">
<?php foreach( $GLOBALS['query_filters'] as $key => $name ):
// get the field's settings without attempting to load a value
$field = get_field_object($key, false, false);
// set value if available
if( isset($_GET[ $name ]) ) {
$field['value'] = explode(',', $_GET[ $name ]);
}
// create filter
?>
<div class="filter" data-filter="<?php echo $name; ?>">
<?php create_field( $field ); ?>
</div>
<?php endforeach; ?>
<input type="hidden" class="js-filter-url" value="<?php echo home_url('products'); ?>" />
</div>
<div class="product-grid">
<?php
/* Start the Loop */
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/post/content', 'product' );
endwhile; ?>
</div>
</div>
<?php else : ?>
<div class="container-s">
<div id="primary" class="content">
<?php get_template_part( 'template-parts/post/content', 'none' ); ?>
</div>
</div>
<?php endif; ?>
This is in my functions.php:
$GLOBALS['query_filters'] = array(
'pb_region' => 'region'
);
// action
add_action('pre_get_posts', 'tmr_filter', 10, 1);
function tmr_filter( $query ) {
// bail early if is in admin
if( is_admin() ) return;
// bail early if not main query
// - allows custom code / plugins to continue working
if( !$query->is_main_query() ) return;
// get meta query
$meta_query = $query->get('meta_query');
// loop over filters
foreach( $GLOBALS['query_filters'] as $key => $name ) {
// continue if not found in url
if( empty($_GET[ $name ]) ) {
continue;
}
// get the value for this filter
// eg: http://www.website.com/events?city=melbourne,sydney
$value = explode(',', $_GET[ $name ]);
//append meta query
$meta_query = array(
'key' => $name,
'value' => $value,
'compare' => 'IN'
);
}
// update meta query
$query->set('meta_query', $meta_query);
}
Any pointers? Many thanks in advance!
Hi @James,
Thank you, that’s exactly what I needed 🙂 I know I really need to brush up on my php, I don’t do it often enough I suppose. But thanks again for the help, much appreciated!
Hi @James,
Sure, no problem! The first screenshot is of the data in the backend, the second is the output of the code you provided and the third is what I’m aiming for (it’s supposed to end up looking like a dropdown). Hope that helps!
Hi @James,
Thank you! I tried the snippet you posted but it returns all the available keys for each row, instead of just the key corresponding with it. Let me explain: A single product I’m using for testing has six URLs “attached” to it: four for EU, one for AU and one for UK. Every URL, however, returns the values eu, uk and au instead of ‘eu’ for the European URLs, ‘au’ for the Australian URLs etc.
Hi @James, sure thing, I’ve added it as an attachment 🙂
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.