0

I'm extending Wordpress REST API with a custom plugin, and I'm in the need of adding a new field to the user response.

The problem is that this field has to appear only in base of the user role.

For example I want a field custom_field appear in the response only if the user is administrator and not contributor.

At the moment I'm using the register_rest_field() function, but it allows me to chose only the type of object.

Do you know if there is a workaround to this issue? Or do you know better ways to reach the same result?

P.S. I'm using WP 4.7.3

0

You can use the filter rest_prepare_user

Something like this should do the trick I think.

function my_rest_prepare_user( WP_REST_Response $response, WP_User $user, WP_REST_Request $request ){

    if( in_array( 'administrator', $user->roles ) ){

        $data = $response->get_data();

        $data['custom_field'] = get_user_meta( $user->ID, 'custom_field', true );

        $response->set_data( $data );

    }

    return $response;

}
add_filter( 'rest_prepare_user', 'my_rest_prepare_user', 10, 3 );

EDIT

If you need to update the user you can register a custom route

function yoursite_update_user( WP_REST_Request $request ){

    $user = get_user_by( 'id', $request->get_param( 'id' ) );

    if( $user && in_array( 'administrator', $user->roles ) ){

        $value = $request->get_param( 'my_field' );

        update_user_meta( $request->get_param( 'id' ), 'my_field', $value );

        return new WP_REST_Response( [
            'code'    => 'user_updated',
            'message' =>  'User Updated'
        ], 200 );

    } else {

        return new WP_REST_Response( [
            'code'    => 'invalid_user',
            'message' =>  'Invalid user'
        ], 404 );

    }

}

register_rest_route( 'yoursite/v1', '/users/update_my_field/(?P<id>\d+)', array(
    'methods'             => WP_REST_Server::EDITABLE,
    'callback'            => 'yoursite_update_user',
    'permission_callback' => function () {
        return current_user_can( 'edit_users' );
    },
    'args'                => array(
        'id' => array(
            'validate_callback' => function ( $param, $request, $key ) {
                return is_numeric( $param );
            }
        ),
    ),
) );

The above route would be triggered by an authenticated POST request to: http:://yoursite.com/wp-json/yoursite/v1/users/update_my_field/{USER_ID} with a post field of my_field

  • It works! But how can I handle the UPDATE call if I don't register the field? – Michele Fortunato Mar 10 '17 at 19:59
  • @MicheleFortunato I have added an example of a custom route to update the user. – Ben Casey Mar 11 '17 at 3:32
  • I would have preferred to stick to the WP REST structure. Adding an endpoint only to handle the update it's a quite dirty workaround in my opinion. I'll wait to see if someone has better solutions in mind before accepting the answer. If there's nothing suitable in the WP core, maybe someone should suggest to implement this feature. It's not uncommon to have different types of users with different fields to populate. Thanks a lot by the way! I didn't now about the rest_prepare_user filter – Michele Fortunato Mar 11 '17 at 5:28
  • I do not believe it is available in core, as I was digging around extensively to write this answer ;) – Ben Casey Mar 11 '17 at 5:31
  • Maybe it's time for a ticket then! – Michele Fortunato Mar 11 '17 at 6:23
0

I found a better workaround using the same filter suggested by @ben-casey in his answer.

Firstly I registered throuhg register_rest_field all the custom fields of all the user types I have in the database.

Then in rest_prepare_user, insted adding the wanted fields, I removed the unwanted ones. In this way I can still use the same endpoint to update the field.

Below an example of the JSON clean up.

function my_rest_prepare_user( WP_REST_Response $response, WP_User $user, WP_REST_Request $request ){

    if( in_array( 'administrator', $user->roles ) ){

        $data = $response->get_data();

        unset($data['custom_field']);

        $response->set_data( $data );

    }

    return $response;

}
add_filter( 'rest_prepare_user', 'my_rest_prepare_user', 10, 3 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.