Question

I have a posttype 'timeslip' and I am calling this with the following API endpoint:

/wp-json/wp/v2/timeslip?meta_key=user_id&meta_value=1

I have exposed my custom field user_id to the API meta and can see it in the response.

add_filter('rest_timeslip_query', array($this, 'timeslip_meta_request_params'));

 public function register_meta_api() {

    // Meta Fields that should be added to the API 
    $timeslip_meta_fields = array(
        'user_id',
        'total_time',
        'start_time',
        'end_time',
    );

    // Meta
    foreach ($timeslip_meta_fields as $field) {
        register_rest_field('timeslip',
            $field,
            array(
                'get_callback'    =>  array($this, 'get_meta'),
                'update_callback' => array($this, 'update_meta'),
                'schema'          =>  null,
            )
        );
    }

}

public function get_meta($object, $field_name) {

    return get_post_meta($object['id'], $field_name);

}

However nothing is filtered.

public function timeslip_meta_request_params($args, $request) {

    $args['meta_key'] = $request['timeslip_user_id'];
    $args['meta_value'] = intval($request['timeslip_user_id']);

    $valid_vars = array_merge( $args, array( 'meta_key', 'meta_value' ) );
    return $valid_vars;


    // $args['meta_key'] = 'user_id';
    // $args['meta_value'] = 1;

    return $args;

}

If I set the $args manually then it works so I guess something is not being passed in.

Reading around it seems the documentation has changed a lot it is hard to find the right way to do this.

Any help much appreciated!

Was it helpful?

Solution

Add a third parameter in the get_post_meta() function as true, that will return the single value of the current post meta, if you don't set it it will return an array of the values.

What is happening now is that internally the query is trying to compare the meta_value with an array instead of a string or integer and that's why you don't get any results.

Also, your requested data should be the same name as the query params indicated in the current endpoint, if you put:

/wp-json/wp/v2/timeslip?meta_key=user_id&meta_value=1

Then you access to the request data as:

$request['meta_key'];
$request['meta_value'];

You originally set the requested data as:

$request['timeslip_user_id'];
$request['timeslip_user_id'];

So your query filter function should looks like this:

function timeslip_meta_request_params( $args, $request ) {
    $args['meta_key']   = $request['meta_key'];
    $args['meta_value'] = $request['meta_value'];

    return $args;
}

I just tested the code in a local env, check that the user_id field is an string. Hope if works for you:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top