I'm using Version 2.0-beta15
with a custom post type that inherits from the WP_REST_Posts_Controller, but needs to query for a date based on an acf field. Yikes!
Endpoint Params
/wp-json/wp/v2/almanac_entry?per_page=3&filter[orderby]=acf_almanac_date&after=2016-12-23T00:00:00&filter[date_query[column]]=acf_almanac_date
The Response
The response returns three items but should only be two, where two are after the date listed, and the third is before the date listed. Below are the three item values of the acf_almanac_date
field:
Code
Actions are registered as:
add_action( 'init', 'register_custom_post_types' );
function register_custom_post_types() {
global $wp_post_types;
$post_type_name = 'almanac_entry';
if( isset( $wp_post_types[ $post_type_name ] ) ) {
$wp_post_types[$post_type_name]->show_in_rest = true;
$wp_post_types[$post_type_name]->rest_base = $post_type_name;
$wp_post_types[$post_type_name]->rest_controller_class = 'WP_REST_Posts_Controller';
}
}
add_action( 'rest_api_init', 'wp_rest_add_custom_fields' );
function wp_rest_add_custom_fields() {
register_rest_field('almanac_entry', 'acf_almanac_date', array (
'get_callback' => function($object, $field_name, $request) {
return get_post_meta( $object[ 'id' ], 'almanac_date', true ) . "T00:00:00";
},
'update_callback' => null,
'schema' => null,
));
}
Any help is much appreciated.
Revelation 1
It occurred to me that, perhaps, the param filter[date_query[column]]=acf_almanac_date
has WP-API querying for the field acf_almanac_date
that is added dynamically in the wp_rest_add_custom_fields
function.
Maybe I need to extend the WP_REST_Posts_Controller and override the prepare_items_query
function? If true, how might I correlate that to the ACF field acf_almanac_date
? Oy vey!
The WordPress REST API doesn't permit querying by post meta values out of the box because it considers them private. To enable querying by a post meta value, you'll need to:
WP_Query
.Here's a bit of code that works for WordPress 4.7:
// Set the post type to modify.
$post_type = 'almanac_entry';
/**
* Register `almanac_date_before` and `almanac_date_after`
* as collection query params.
*
* Also support ordering by the `almanac_date` meta value.
*/
add_filter( "rest_{$post_type}_collection_params", function( $params ){
$params['almanac_date_before'] = array(
'description' => __( 'Limit response to posts published before a given ISO8601 compliant date.' ),
'type' => 'string',
'format' => 'date-time',
);
$params['almanac_date_after'] = array(
'description' => __( 'Limit response to posts published after a given ISO8601 compliant date.' ),
'type' => 'string',
'format' => 'date-time',
);
$params['orderby']['enum'][] = 'almanac_date';
return $params;
});
/**
* Transform almanac_date_before` and `almanac_date_after` into a meta query.
*/
add_filter( "rest_{$post_type}_query", function( $query_args, $request ){
if ( isset( $request['almanac_date_before'] ) ) {
if ( ! is_array( $query_args['meta_query'] ) ) {
$query_args['meta_query'] = array();
}
// We only want the 2016-11-23 from 2016-11-23T00:00:00
$bits = explode( 'T', $request['almanac_date_before'] );
$query_args['meta_query'][] = array(
'key' => 'almanac_date',
'value' => $bits[0],
'compare' => '<=',
'type' => 'DATE',
);
}
if ( isset( $request['almanac_date_after'] ) ) {
if ( ! is_array( $query_args['meta_query'] ) ) {
$query_args['meta_query'] = array();
}
// We only want the 2016-11-23 from 2016-11-23T00:00:00
$bits = explode( 'T', $request['almanac_date_after'] );
$query_args['meta_query'][] = array(
'key' => 'almanac_date',
'value' => $bits[0],
'compare' => '>=',
'type' => 'DATE',
);
}
return $query_args;
}, 10, 2 );