wp/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
--- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-controller.php	Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-controller.php	Fri Sep 05 18:40:08 2025 +0200
@@ -12,6 +12,7 @@
  *
  * @since 4.7.0
  */
+#[AllowDynamicProperties]
 abstract class WP_REST_Controller {
 
 	/**
@@ -288,15 +289,15 @@
 	 *
 	 * @since 4.7.0
 	 *
-	 * @param array  $data    Response data to filter.
-	 * @param string $context Context defined in the schema.
+	 * @param array  $response_data Response data to filter.
+	 * @param string $context       Context defined in the schema.
 	 * @return array Filtered response.
 	 */
-	public function filter_response_by_context( $data, $context ) {
+	public function filter_response_by_context( $response_data, $context ) {
 
 		$schema = $this->get_item_schema();
 
-		return rest_filter_response_by_context( $data, $schema, $context );
+		return rest_filter_response_by_context( $response_data, $schema, $context );
 	}
 
 	/**
@@ -411,11 +412,11 @@
 	 *
 	 * @since 4.7.0
 	 *
-	 * @param array           $prepared Prepared response array.
-	 * @param WP_REST_Request $request  Full details about the request.
+	 * @param array           $response_data Prepared response array.
+	 * @param WP_REST_Request $request       Full details about the request.
 	 * @return array Modified data object with additional fields.
 	 */
-	protected function add_additional_fields_to_object( $prepared, $request ) {
+	protected function add_additional_fields_to_object( $response_data, $request ) {
 
 		$additional_fields = $this->get_additional_fields();
 
@@ -430,10 +431,16 @@
 				continue;
 			}
 
-			$prepared[ $field_name ] = call_user_func( $field_options['get_callback'], $prepared, $field_name, $request, $this->get_object_type() );
+			$response_data[ $field_name ] = call_user_func(
+				$field_options['get_callback'],
+				$response_data,
+				$field_name,
+				$request,
+				$this->get_object_type()
+			);
 		}
 
-		return $prepared;
+		return $response_data;
 	}
 
 	/**
@@ -441,11 +448,11 @@
 	 *
 	 * @since 4.7.0
 	 *
-	 * @param object          $object  Data model like WP_Term or WP_Post.
-	 * @param WP_REST_Request $request Full details about the request.
+	 * @param object          $data_object Data model like WP_Term or WP_Post.
+	 * @param WP_REST_Request $request     Full details about the request.
 	 * @return true|WP_Error True on success, WP_Error object if a field cannot be updated.
 	 */
-	protected function update_additional_fields_for_object( $object, $request ) {
+	protected function update_additional_fields_for_object( $data_object, $request ) {
 		$additional_fields = $this->get_additional_fields();
 
 		foreach ( $additional_fields as $field_name => $field_options ) {
@@ -458,7 +465,14 @@
 				continue;
 			}
 
-			$result = call_user_func( $field_options['update_callback'], $request[ $field_name ], $object, $field_name, $request, $this->get_object_type() );
+			$result = call_user_func(
+				$field_options['update_callback'],
+				$request[ $field_name ],
+				$data_object,
+				$field_name,
+				$request,
+				$this->get_object_type()
+			);
 
 			if ( is_wp_error( $result ) ) {
 				return $result;
@@ -562,8 +576,10 @@
 		$additional_fields = $this->get_additional_fields();
 
 		foreach ( $additional_fields as $field_name => $field_options ) {
-			// For back-compat, include any field with an empty schema
-			// because it won't be present in $this->get_item_schema().
+			/*
+			 * For back-compat, include any field with an empty schema
+			 * because it won't be present in $this->get_item_schema().
+			 */
 			if ( is_null( $field_options['schema'] ) ) {
 				$properties[ $field_name ] = $field_options;
 			}
@@ -581,6 +597,18 @@
 
 		$fields = array_keys( $properties );
 
+		/*
+		 * '_links' and '_embedded' are not typically part of the item schema,
+		 * but they can be specified in '_fields', so they are added here as a
+		 * convenience for checking with rest_is_field_included().
+		 */
+		$fields[] = '_links';
+		if ( $request->has_param( '_embed' ) ) {
+			$fields[] = '_embedded';
+		}
+
+		$fields = array_unique( $fields );
+
 		if ( ! isset( $request['_fields'] ) ) {
 			return $fields;
 		}
@@ -597,15 +625,17 @@
 		// Return the list of all requested fields which appear in the schema.
 		return array_reduce(
 			$requested_fields,
-			static function( $response_fields, $field ) use ( $fields ) {
+			static function ( $response_fields, $field ) use ( $fields ) {
 				if ( in_array( $field, $fields, true ) ) {
 					$response_fields[] = $field;
 					return $response_fields;
 				}
 				// Check for nested fields if $field is not a direct match.
 				$nested_fields = explode( '.', $field );
-				// A nested field is included so long as its top-level property
-				// is present in the schema.
+				/*
+				 * A nested field is included so long as its top-level property
+				 * is present in the schema.
+				 */
 				if ( in_array( $nested_fields[0], $fields, true ) ) {
 					$response_fields[] = $field;
 				}