Make WordPress Core


Ignore:
Timestamp:
05/04/2020 02:44:44 AM (4 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Support more JSON Schemas when filtering a response by context.

The array type, multi-types, and the additional properties keyword are now supported. Additionally, the filter recurses to an infinite depth.

Fixes #48819.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api.php

    r47753 r47758  
    16591659    return $rels;
    16601660}
     1661
     1662/**
     1663 * Filters the response to remove any fields not available in the given context.
     1664 *
     1665 * @since 5.5.0
     1666 *
     1667 * @param array|object $data    The response data to modify.
     1668 * @param array        $schema  The schema for the endpoint used to filter the response.
     1669 * @param string       $context The requested context.
     1670 * @return array|object The filtered response data.
     1671 */
     1672function rest_filter_response_by_context( $data, $schema, $context ) {
     1673    if ( ! is_array( $data ) && ! is_object( $data ) ) {
     1674        return $data;
     1675    }
     1676
     1677    if ( isset( $schema['type'] ) ) {
     1678        $type = $schema['type'];
     1679    } elseif ( isset( $schema['properties'] ) ) {
     1680        $type = 'object'; // Back compat if a developer accidentally omitted the type.
     1681    } else {
     1682        return $data;
     1683    }
     1684
     1685    foreach ( $data as $key => $value ) {
     1686        $check = array();
     1687
     1688        if ( 'array' === $type || ( is_array( $type ) && in_array( 'array', $type, true ) ) ) {
     1689            $check = isset( $schema['items'] ) ? $schema['items'] : array();
     1690        } elseif ( 'object' === $type || ( is_array( $type ) && in_array( 'object', $type, true ) ) ) {
     1691            if ( isset( $schema['properties'][ $key ] ) ) {
     1692                $check = $schema['properties'][ $key ];
     1693            } elseif ( isset( $schema['additionalProperties'] ) && is_array( $schema['additionalProperties'] ) ) {
     1694                $check = $schema['additionalProperties'];
     1695            }
     1696        }
     1697
     1698        if ( ! isset( $check['context'] ) ) {
     1699            continue;
     1700        }
     1701
     1702        if ( ! in_array( $context, $check['context'], true ) ) {
     1703            if ( is_object( $data ) ) {
     1704                unset( $data->$key );
     1705            } else {
     1706                unset( $data[ $key ] );
     1707            }
     1708        } elseif ( is_array( $value ) || is_object( $value ) ) {
     1709            $new_value = rest_filter_response_by_context( $value, $check, $context );
     1710
     1711            if ( is_object( $data ) ) {
     1712                $data->$key = $new_value;
     1713            } else {
     1714                $data[ $key ] = $new_value;
     1715            }
     1716        }
     1717    }
     1718
     1719    return $data;
     1720}
Note: See TracChangeset for help on using the changeset viewer.