WP-API获取特定日期后的帖子


WP-API Get Posts After a Specific Date

我使用Version 2.0-beta15与自定义的帖子类型,从WP_REST_Posts_Controller继承,但需要查询基于一个acf字段的日期。呵!

端点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

响应

响应返回三个项目,但应该只有两个,其中两个在列出的日期之后,第三个在列出的日期之前。以下是acf_almanac_date字段的三个项目值:

  1. 2016 - 12 - 31 t00:00:00
  2. 2016 - 12 - 24 t00:00:00
  3. 2016-12-17T00:00:00(此日期在2016-12-23T00:00:00之前,本应返回)

动作注册为:

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,
  ));
}

任何帮助都非常感谢。


启示1

我突然想到,也许,参数filter[date_query[column]]=acf_almanac_date具有WP-API查询字段acf_almanac_date是在wp_rest_add_custom_fields函数中动态添加的。

也许我需要扩展WP_REST_Posts_Controller并覆盖prepare_items_query函数?如果为真,我如何将其与ACF字段acf_almanac_date关联起来?Oy一!

WordPress REST API不允许通过post元值开箱查询,因为它认为它们是私有的。要启用post元值查询,您需要:

  1. 向Post控制器注册查询参数
  2. 将请求参数转换为传递给WP_Query的查询参数

下面是一段适用于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 );