Home › Forums › General Issues › Filter products/categories/ by ACF field
Hello,
I try to filter the list of categories of the products received bu the rest api.
I add ‘myfield’ as ACF field.
With the plugin ACF-to-rest-api I can see the field in the rest api result under acf : {}
This url returns all the categories.
https://mywebsite/wp-json/wc/v3/products/categories/
I want to be able to filter a custom field added by ACF
https://mywebsite/wp-json/wc/v3/products/categories/?myfield=testvalue
Could someone help me ?
I suppose there is a filter or an action to add in the functions.php file but everything I tried returned all the categories without any filter.
What’s also strange, for the products, I can see in the rest api result the metadata with the values added by ACF
For the category, the metadata aren’t visible.
In the database the values are stored in termmeta for the categories and in postmeta for the products.
If I’m right, the product is a post and the category is a taxonomy.
Thanks in advance,
Ok I think I understand what you are trying to do, but correct my if I’m wrong.
You want to retrieve TERMS from the taxonomy CATEGORY, but only those terms that have a specific value filled out in a custom field.
There is an article in the ACF documentation describing how to do this if you were querying posts instead of taxonomy-terms: https://www.advancedcustomfields.com/resources/creating-wp-archive-custom-field-filter/
However, I believe the same principle can be applied to pre_get_terms
(instead of pre_get_posts).
The filter pre_get_terms is called inside WP_Term_Query so it should work for api requests: https://developer.wordpress.org/reference/classes/wp_term_query/get_terms/
I’m not sure I explained well what I try to reach…
To be sure :
Products = post
Categories = taxonomy
When I go to this endpoint : https://mywebsite/wp-json/wc/v3/products/categories/
I receive all the categories available for the products from the api.
So there isn’t any filter. Screenshot enclose
Before I will create a new category I need to know if the category already exist or not.
I add a ACF field on the category to insert a unique ID.
On the screenshot you can see coming from the plugin ACF-to-rest-api
“acf”: {
“id_category_mercator”: “merca1”
},
So the unique ID is “merca1”
Now I want to ask the api to return me all the categories where there is “merca1” in the field “id_category_mercator”.
Those values are stored in the table termmeta
If it’s working, the api will return me 1 category and not all the list.
Is it so more clear what I’m looking for or are your samples the correct ones ?
Thanks in advance,
I believe my earlier example could work, I have modified the code from the acf-article and I believe this should work:
$GLOBALS['my_query_filters'] = array(
'field_1' => 'id_category_mercator',
);
add_action('pre_get_terms', 'my_pre_get_terms', 10, 1);
function my_pre_get_terms( $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['my_query_filters'] as $key => $name ) {
// continue if not found in url
if( empty($_GET[ $name ]) ) {
continue;
}
// get the value for this filter
// eg: https://mywebsite/wp-json/wc/v3/products/category?id_category_mercator=merca1
$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);
}
All I did was change the $GLOBALS variable at the top to use your acf fieldname, and then I changed the names of the filter and the function.
I don’t know if this will work because I’m not sure if ACF data on categories is really stored in the term_meta table. But you could add this to your functions.php and try to query the category endpoint with ?id_category_mercator=merca1
we could find out.
Unfortunately I receive now an error on my request :
Fatal error: Uncaught Error: Call to undefined method WP_Term_Query::is_main_query()
If I comment your line
if( !$query->is_main_query() ) return;
I receive another error : Fatal error: Uncaught Error: Call to undefined method WP_Term_Query::get()
For the line
$meta_query = $query->get('meta_query');
I can confirm you that the ACF data’s are for the categories are stored in the “termmeta” table. Please check screenshot.
I have experimented a bit and I can confirm the following works for regular categories:
$GLOBALS['my_query_filters'] = array(
'field_1' => 'id_category_mercator',
);
add_action('pre_get_terms', 'my_pre_get_terms', 10, 1);
function my_pre_get_terms( $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->meta_query;
// loop over filters
foreach( $GLOBALS['my_query_filters'] as $key => $name ) {
// continue if not found in url
if( empty($_GET[ $name ]) ) {
continue;
}
// get the value for this filter
// eg: https://mywebsite/wp-json/wc/v3/products/category?id_category_mercator=merca1
$value = explode(',', $_GET[ $name ]);
// append meta query
$meta_query->queries[] = array(
'key' => $name,
'value' => $value,
'compare' => 'IN',
);
}
// update meta query
$query->meta_query = $meta_query;
}
You might want to figure something out to replace the commented out line of code:
//if( !$query->is_main_query() ) return;
But I don’t know what other functionality your project has that could cause/suffer conflicts.
Hello,
Thanks a lot. That’s seems also to work for me.
For the code
if( !$query->is_main_query() )
isn’t it a possibility to check if the field is inside the url ?
if( isset($_GET['id_article_mercator'])
After that I can’t post a value … Is it better to create a new post for that or do you have a quick solution ?
You must be logged in to reply to this topic.
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 Privacy Policy. If you continue to use this site, you consent to our use of cookies.