rest_filter_response_by_context

The timeline below displays how wordpress function rest_filter_response_by_context has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

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;
}

WordPress Version: 5.6

/**
 * 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 $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($data, $schema, $context)
{
    if (isset($schema['anyOf'])) {
        $matching_schema = rest_find_any_matching_schema($data, $schema, '');
        if (!is_wp_error($matching_schema)) {
            if (!isset($schema['type'])) {
                $schema['type'] = $matching_schema['type'];
            }
            $data = rest_filter_response_by_context($data, $matching_schema, $context);
        }
    }
    if (isset($schema['oneOf'])) {
        $matching_schema = rest_find_one_matching_schema($data, $schema, '', true);
        if (!is_wp_error($matching_schema)) {
            if (!isset($schema['type'])) {
                $schema['type'] = $matching_schema['type'];
            }
            $data = rest_filter_response_by_context($data, $matching_schema, $context);
        }
    }
    if (!is_array($data) && !is_object($data)) {
        return $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 $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($data)) {
            $is_object_type = false;
        } else {
            $is_array_type = false;
        }
    }
    $has_additional_properties = $is_object_type && isset($schema['additionalProperties']) && is_array($schema['additionalProperties']);
    foreach ($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.
                $data = array();
                break;
            }
            if (is_object($data)) {
                unset($data->{$key});
            } else {
                unset($data[$key]);
            }
        } elseif (is_array($value) || is_object($value)) {
            $new_value = rest_filter_response_by_context($value, $check, $context);
            if (is_object($data)) {
                $data->{$key} = $new_value;
            } else {
                $data[$key] = $new_value;
            }
        }
    }
    return $data;
}

WordPress Version: 5.5

/**
 * Filters the response to remove any fields not available in the given context.
 *
 * @since 5.5.0
 *
 * @param array|object $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($data, $schema, $context)
{
    if (!is_array($data) && !is_object($data)) {
        return $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 $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($data)) {
            $is_object_type = false;
        } else {
            $is_array_type = false;
        }
    }
    $has_additional_properties = $is_object_type && isset($schema['additionalProperties']) && is_array($schema['additionalProperties']);
    foreach ($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];
            } 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.
                $data = array();
                break;
            }
            if (is_object($data)) {
                unset($data->{$key});
            } else {
                unset($data[$key]);
            }
        } elseif (is_array($value) || is_object($value)) {
            $new_value = rest_filter_response_by_context($value, $check, $context);
            if (is_object($data)) {
                $data->{$key} = $new_value;
            } else {
                $data[$key] = $new_value;
            }
        }
    }
    return $data;
}