Make WordPress Core

Opened 6 years ago

Closed 5 years ago

Last modified 5 years ago

#44432 closed defect (bug) (fixed)

Sometimes, an array is passed to the get_callback provided to register_rest_field() instead of an object

Reported by: salzano's profile salzano Owned by: timothyblynjacobs's profile TimothyBlynJacobs
Milestone: 5.3 Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: reporter-feedback
Focuses: Cc:

Description

When using register_rest_field() to add fields to terms in the WordPress REST API, the $object sent to your get_callback function will be an array instead of an object like the documentation describes.

An object will still be passed, sometimes, too. Here is an example of how I work around this problem:

	function add_api_term_fields() {

		//location-phone-hours
		register_rest_field( 'location', 'location-phone-hours', array(
			'get_callback'    => array( $this, 'get_term_meta_via_rest' ),
			'update_callback' => array( $this, 'set_term_meta_via_rest' ),
			'schema'          => array(
				'description' => __( 'An array of phone numbers and hours of operation for this location.', 'inventory-portal' ),
				'type'        => 'string',
				'context'     => array( 'view', 'edit' ),
			),
		) );
	}

	static function get_term_meta_via_rest( $term, $attr, $request, $object_type ) {
		$term_id = 0;

		if(  is_array( $term ) ) {
			$term_id = $term['id']
		} else {
			$term_id = $term->term_id;
		}

		return maybe_serialize( get_term_meta( $term_id, $attr, true ) );
	}

Why is this happening? See the definition of prepare_item_for_response() method on line 683 of wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php. The call to add_additional_fields_to_object() on line 725 is the method that passes an array to your get_callback.

Perhaps this is an acceptable design. I believe the only reference to the data type of $object in the documentation is this comment https://developer.wordpress.org/reference/functions/register_rest_field/#comment-2260. It certainly feels like a bug.

Attachments (1)

44432.diff (3.8 KB) - added by TimothyBlynJacobs 5 years ago.

Download all attachments as: .zip

Change History (9)

This ticket was mentioned in Slack in #core-restapi by timothybjacobs. View the logs.


5 years ago

#2 @TimothyBlynJacobs
5 years ago

  • Milestone changed from Awaiting Review to Future Release
  • Owner set to TimothyBlynJacobs
  • Status changed from new to assigned
  • Version changed from 4.9.6 to 4.7

Assigning this to myself to investigate. I think at this point we can really only hope for a docs fix to clarify without breaking BC.

#3 @TimothyBlynJacobs
5 years ago

  • Keywords reporter-feedback added

I looked at all the usages of add_additional_fields_to_object and update_additional_fields_for_object

Autosaves
- Add Fields: Passes prepared data as an array.

Comments
- Add Fields: Passes prepared data as an array.
- Update fields: Passes WP_Comment object.

Post Statuses
- Add Fields: Passes prepared data as an array.

Post Types
- Add Fields: Passes prepared data as an array.

Posts
- Add Fields: Passes prepared data as an array.
- Update fields: Passes WP_Post object.

Revisions
- Add Fields: Passes prepared data as an array.

Search
- Add Fields: Passes prepared data as an array.

Taxonomies
- Add Fields: Passes prepared data as an array.

Terms
- Add Fields: Passes prepared data as an array.
- Update fields: Passes WP_Term object.

Themes
- Add Fields: Passes prepared data as an array.

Users
- Add Fields: Passes prepared data as an array.
- Update fields: Passes WP_User object.

Attachments
- Update fields: Passes WP_Post object.

As far as I can tell, the REST API always passes an array to the get_callback() and always passes an entity object to the update_callback.

An object will still be passed, sometimes, too.

Could you clarify when this happens?

Perhaps this has been fixed in the meantime?

The documentation certainly could use updating as well.

This ticket was mentioned in Slack in #core-restapi by timothybjacobs. View the logs.


5 years ago

This ticket was mentioned in Slack in #core-restapi by timothybjacobs. View the logs.


5 years ago

#6 @kadamwhite
5 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 45810:

REST API: Clarify arguments passed to rest route get & update callbacks.

Update doc block argument definitions to clarify that the REST API always passes an array to the get_callback and always passes an entity object to the update_callback.

Props TimothyBlynJacobs, salzano.
Fixes #44432.

#7 @kadamwhite
5 years ago

  • Milestone changed from Future Release to 5.3

Committed the docs change clarifying this behavior for 5.3.

#8 @kadamwhite
5 years ago

@salzano Thank you for calling this out. It does appear to my eyes that the functionality is internally consistent and that the major oversight was a lack of documentation. I've committed @TimothyBlynJacobs' patch to update the documentation, and provisionally closed this as fixed; if however you determine that there is a case we're overlooking please note it here or message us to indicate this should be reopened and continued. Thank you for your contribution!

Note: See TracTickets for help on using tickets.