WordPress Version: 6.2
/**
* Filters the response to remove any fields not available in the given context.
*
* @since 5.5.0
* @since 5.6.0 Support the "patternProperties" keyword for objects.
* Support the "anyOf" and "oneOf" keywords.
*
* @param array|object $response_data The response data to modify.
* @param array $schema The schema for the endpoint used to filter the response.
* @param string $context The requested context.
* @return array|object The filtered response data.
*/
function rest_filter_response_by_context($response_data, $schema, $context)
{
if (isset($schema['anyOf'])) {
$matching_schema = rest_find_any_matching_schema($response_data, $schema, '');
if (!is_wp_error($matching_schema)) {
if (!isset($schema['type'])) {
$schema['type'] = $matching_schema['type'];
}
$response_data = rest_filter_response_by_context($response_data, $matching_schema, $context);
}
}
if (isset($schema['oneOf'])) {
$matching_schema = rest_find_one_matching_schema($response_data, $schema, '', true);
if (!is_wp_error($matching_schema)) {
if (!isset($schema['type'])) {
$schema['type'] = $matching_schema['type'];
}
$response_data = rest_filter_response_by_context($response_data, $matching_schema, $context);
}
}
if (!is_array($response_data) && !is_object($response_data)) {
return $response_data;
}
if (isset($schema['type'])) {
$type = $schema['type'];
} elseif (isset($schema['properties'])) {
$type = 'object';
// Back compat if a developer accidentally omitted the type.
} else {
return $response_data;
}
$is_array_type = 'array' === $type || is_array($type) && in_array('array', $type, true);
$is_object_type = 'object' === $type || is_array($type) && in_array('object', $type, true);
if ($is_array_type && $is_object_type) {
if (rest_is_array($response_data)) {
$is_object_type = false;
} else {
$is_array_type = false;
}
}
$has_additional_properties = $is_object_type && isset($schema['additionalProperties']) && is_array($schema['additionalProperties']);
foreach ($response_data as $key => $value) {
$check = array();
if ($is_array_type) {
$check = isset($schema['items']) ? $schema['items'] : array();
} elseif ($is_object_type) {
if (isset($schema['properties'][$key])) {
$check = $schema['properties'][$key];
} else {
$pattern_property_schema = rest_find_matching_pattern_property_schema($key, $schema);
if (null !== $pattern_property_schema) {
$check = $pattern_property_schema;
} elseif ($has_additional_properties) {
$check = $schema['additionalProperties'];
}
}
}
if (!isset($check['context'])) {
continue;
}
if (!in_array($context, $check['context'], true)) {
if ($is_array_type) {
// All array items share schema, so there's no need to check each one.
$response_data = array();
break;
}
if (is_object($response_data)) {
unset($response_data->{$key});
} else {
unset($response_data[$key]);
}
} elseif (is_array($value) || is_object($value)) {
$new_value = rest_filter_response_by_context($value, $check, $context);
if (is_object($response_data)) {
$response_data->{$key} = $new_value;
} else {
$response_data[$key] = $new_value;
}
}
}
return $response_data;
}