tl;dr You can get all the fields stored in Advanced Custom Field with:
$groups = apply_filters( 'acf/get_field_groups', array() );
if ( is_array( $groups ) ) {
foreach ( $groups as $group ) {
$fields = apply_filters( 'acf/field_group/get_fields', array(), $group['id'] );
return $fields;
}
}
For my The Events Calendar Shortcode Pro plugin, I wanted to add the ability to filter by a field added with Advanced Custom Fields. This way with a field named additional_data someone could use the following shortcode to only list events with the value “Test Data” in that field:
[ecs-list-events additional_data="Test Data"]
So I started looking for documentation on getting all field groups from Advanced Custom Fields and then getting all the fields in each group, but the documentation for getting the groups was a bit thin.
I thought you could do something like:
$groups = get_field_groups();
But Advanced Custom Field actually hides this function within a class:
class acf_field_group
{
var $settings;
/*
* __construct
*
* @description:
* @since 3.1.8
* @created: 23/06/12
*/
function __construct()
{
// actions
add_action('admin_enqueue_scripts', array($this,'admin_enqueue_scripts'));
// filters
add_filter('acf/get_field_groups', array($this, 'get_field_groups'), 1, 1);
add_filter('acf/field_group/get_fields', array($this, 'get_fields'), 5, 2);
// ...
}
function get_field_groups( $array )
{
// cache
$found = false;
$cache = wp_cache_get( 'field_groups', 'acf', false, $found );
if( $found )
{
return $cache;
}
// get acf's
$posts = get_posts(array(
'numberposts' => -1,
'post_type' => 'acf',
'orderby' => 'menu_order title',
'order' => 'asc',
'suppress_filters' => false,
));
// populate acfs
if( $posts ){ foreach( $posts as $post ){
$array[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'menu_order' => $post->menu_order,
);
}}
// set cache
wp_cache_set( 'field_groups', $array, 'acf' );
return $array;
}
// ...
}
new acf_field_group();
We can’t just call the get_field_groups function directly because the instance of the acf_field_group class isn’t available to us. We could create another instance with
new acf_field_group()
somewhere in our code, but then we have two copies of the class running for no reason (and might mess things up with the filters being registered twice).
Unlike a normal filter which would take some data and either return it back or modify it, the get_field_groups function is ignoring the input value of $array and just returning the data for the field groups no matter what.
So you’re actually applying a filter to fetch the data, which isn’t really filtering anything:
$groups = apply_filters( 'acf/get_field_groups', array() );
Whereas normally the data would be fetched first into $groups and then apply_filters called so others can modify it, ie.:
$groups = ... some code to get the groups data ...; $groups = apply_filters( 'acf/get_field_groups', $groups );
We can still hook into the acf/get_field_groups filter and modify the field groups after get_field_groups provides it, but the initial data isn’t available before the acf/get_field_groups filter is initially run.
Interesting usage of WordPress filters and not something I’ve seen done before!