Make WordPress Core

Ticket #48819: 48819.diff

File 48819.diff, 11.8 KB (added by TimothyBlynJacobs, 4 years ago)
  • src/wp-includes/rest-api.php

    diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
    index c5093cc33b..263a8eea61 100644
    a b function rest_preload_api_request( $memo, $path ) { 
    15611561
    15621562        return $memo;
    15631563}
     1564
     1565
     1566/**
     1567 * Filters the response to remove any fields not available in the given context.
     1568 *
     1569 * @since 5.4.0
     1570 *
     1571 * @param array|object $data    The response data to modify.
     1572 * @param array        $schema  The schema for the endpoint used to filter the response.
     1573 * @param string       $context The requested context.
     1574 * @return array|object The filtered response data.
     1575 */
     1576function rest_filter_response_by_context( $data, $schema, $context ) {
     1577        if ( ! is_array( $data ) && ! is_object( $data ) ) {
     1578                return $data;
     1579        }
     1580
     1581        if ( isset( $schema['type'] ) ) {
     1582                $type = $schema['type'];
     1583        } elseif ( isset( $schema['properties'] ) ) {
     1584                $type = 'object'; // Back compat if a developer accidentally omitted the type.
     1585        } else {
     1586                return $data;
     1587        }
     1588
     1589        foreach ( $data as $key => $value ) {
     1590                $check = array();
     1591
     1592                if ( 'array' === $type || ( is_array( $type ) && in_array( 'array', $type, true ) ) ) {
     1593                        $check = isset( $schema['items'] ) ? $schema['items'] : array();
     1594                } elseif ( 'object' === $type || ( is_array( $type ) && in_array( 'object', $type, true ) ) ) {
     1595                        if ( isset( $schema['properties'][ $key ] ) ) {
     1596                                $check = $schema['properties'][ $key ];
     1597                        } elseif ( isset( $schema['additionalProperties'] ) && is_array( $schema['additionalProperties'] ) ) {
     1598                                $check = $schema['additionalProperties'];
     1599                        }
     1600                }
     1601
     1602                if ( isset( $check['context'] ) && ! in_array( $context, $check['context'], true ) ) {
     1603                        if ( is_object( $data ) ) {
     1604                                unset( $data->$key );
     1605                        } else {
     1606                                unset( $data[ $key ] );
     1607                        }
     1608                } else {
     1609                        $new_value = rest_filter_response_by_context( $value, $check, $context );
     1610
     1611                        if ( is_object( $data ) ) {
     1612                                $data->$key = $new_value;
     1613                        } else {
     1614                                $data[ $key ] = $new_value;
     1615                        }
     1616                }
     1617        }
     1618
     1619        return $data;
     1620}
  • src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
    index 90b97f0f3b..f90ed7cdb3 100644
    a b abstract class WP_REST_Controller { 
    234234         *
    235235         * @since 4.7.0
    236236         *
    237          * @param array  $data    Response data to fiter.
     237         * @param array  $data    Response data to filter.
    238238         * @param string $context Context defined in the schema.
    239239         * @return array Filtered response.
    240240         */
    abstract class WP_REST_Controller { 
    242242
    243243                $schema = $this->get_item_schema();
    244244
    245                 foreach ( $data as $key => $value ) {
    246                         if ( empty( $schema['properties'][ $key ] ) || empty( $schema['properties'][ $key ]['context'] ) ) {
    247                                 continue;
    248                         }
    249 
    250                         if ( ! in_array( $context, $schema['properties'][ $key ]['context'], true ) ) {
    251                                 unset( $data[ $key ] );
    252                                 continue;
    253                         }
    254 
    255                         if ( 'object' === $schema['properties'][ $key ]['type'] && ! empty( $schema['properties'][ $key ]['properties'] ) ) {
    256                                 foreach ( $schema['properties'][ $key ]['properties'] as $attribute => $details ) {
    257                                         if ( empty( $details['context'] ) ) {
    258                                                 continue;
    259                                         }
    260 
    261                                         if ( ! in_array( $context, $details['context'], true ) ) {
    262                                                 if ( isset( $data[ $key ][ $attribute ] ) ) {
    263                                                         unset( $data[ $key ][ $attribute ] );
    264                                                 }
    265                                         }
    266                                 }
    267                         }
    268                 }
    269 
    270                 return $data;
     245                return rest_filter_response_by_context( $data, $schema, $context );
    271246        }
    272247
    273248        /**
  • tests/phpunit/tests/rest-api.php

    diff --git a/tests/phpunit/tests/rest-api.php b/tests/phpunit/tests/rest-api.php
    index 1efb81a348..3943f8711b 100644
    a b class Tests_REST_API extends WP_UnitTestCase { 
    906906                $this->assertEquals( '/wp/v2/posts', $request->get_route() );
    907907                $this->assertEquals( 'GET', $request->get_method() );
    908908        }
     909
     910        /**
     911         * @dataProvider _dp_rest_filter_response_by_context
     912         */
     913        public function test_rest_filter_response_by_context( $schema, $data, $expected ) {
     914                $this->assertEquals( $expected, rest_filter_response_by_context( $data, $schema, 'view' ) );
     915        }
     916
     917        public function _dp_rest_filter_response_by_context() {
     918                return array(
     919                        'default'                => array(
     920                                array(
     921                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     922                                        'type'       => 'object',
     923                                        'properties' => array(
     924                                                'first'  => array(
     925                                                        'type'    => 'string',
     926                                                        'context' => array( 'view', 'edit' ),
     927                                                ),
     928                                                'second' => array(
     929                                                        'type'    => 'string',
     930                                                        'context' => array( 'edit' ),
     931                                                ),
     932                                        ),
     933                                ),
     934                                array(
     935                                        'first'  => 'a',
     936                                        'second' => 'b',
     937                                ),
     938                                array( 'first' => 'a' ),
     939                        ),
     940                        'keeps missing context'  => array(
     941                                array(
     942                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     943                                        'type'       => 'object',
     944                                        'properties' => array(
     945                                                'first'  => array(
     946                                                        'type'    => 'string',
     947                                                        'context' => array( 'view', 'edit' ),
     948                                                ),
     949                                                'second' => array(
     950                                                        'type' => 'string',
     951                                                ),
     952                                        ),
     953                                ),
     954                                array(
     955                                        'first'  => 'a',
     956                                        'second' => 'b',
     957                                ),
     958                                array(
     959                                        'first'  => 'a',
     960                                        'second' => 'b',
     961                                ),
     962                        ),
     963                        'removes empty context'  => array(
     964                                array(
     965                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     966                                        'type'       => 'object',
     967                                        'properties' => array(
     968                                                'first'  => array(
     969                                                        'type'    => 'string',
     970                                                        'context' => array( 'view', 'edit' ),
     971                                                ),
     972                                                'second' => array(
     973                                                        'type'    => 'string',
     974                                                        'context' => array(),
     975                                                ),
     976                                        ),
     977                                ),
     978                                array(
     979                                        'first'  => 'a',
     980                                        'second' => 'b',
     981                                ),
     982                                array( 'first' => 'a' ),
     983                        ),
     984                        'nested properties'      => array(
     985                                array(
     986                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     987                                        'type'       => 'object',
     988                                        'properties' => array(
     989                                                'parent' => array(
     990                                                        'type'       => 'object',
     991                                                        'context'    => array( 'view', 'edit' ),
     992                                                        'properties' => array(
     993                                                                'child'  => array(
     994                                                                        'type'    => 'string',
     995                                                                        'context' => array( 'view', 'edit' ),
     996                                                                ),
     997                                                                'hidden' => array(
     998                                                                        'type'    => 'string',
     999                                                                        'context' => array( 'edit' ),
     1000                                                                ),
     1001                                                        ),
     1002                                                ),
     1003                                        ),
     1004                                ),
     1005                                array(
     1006                                        'parent' => array(
     1007                                                'child'  => 'hi',
     1008                                                'hidden' => 'there',
     1009                                        ),
     1010                                ),
     1011                                array( 'parent' => array( 'child' => 'hi' ) ),
     1012                        ),
     1013                        'grand child properties' => array(
     1014                                array(
     1015                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     1016                                        'type'       => 'object',
     1017                                        'properties' => array(
     1018                                                'parent' => array(
     1019                                                        'type'       => 'object',
     1020                                                        'context'    => array( 'view', 'edit' ),
     1021                                                        'properties' => array(
     1022                                                                'child' => array(
     1023                                                                        'type'       => 'object',
     1024                                                                        'context'    => array( 'view', 'edit' ),
     1025                                                                        'properties' => array(
     1026                                                                                'grand'  => array(
     1027                                                                                        'type'    => 'string',
     1028                                                                                        'context' => array( 'view', 'edit' ),
     1029                                                                                ),
     1030                                                                                'hidden' => array(
     1031                                                                                        'type'    => 'string',
     1032                                                                                        'context' => array( 'edit' ),
     1033                                                                                ),
     1034                                                                        ),
     1035                                                                ),
     1036                                                        ),
     1037                                                ),
     1038                                        ),
     1039                                ),
     1040                                array(
     1041                                        'parent' => array(
     1042                                                'child' => array(
     1043                                                        'grand' => 'hi',
     1044                                                ),
     1045                                        ),
     1046                                ),
     1047                                array( 'parent' => array( 'child' => array( 'grand' => 'hi' ) ) ),
     1048                        ),
     1049                        'array'                  => array(
     1050                                array(
     1051                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     1052                                        'type'       => 'object',
     1053                                        'properties' => array(
     1054                                                'arr' => array(
     1055                                                        'type'    => 'array',
     1056                                                        'context' => array( 'view', 'edit' ),
     1057                                                        'items'   => array(
     1058                                                                'type'       => 'object',
     1059                                                                'context'    => array( 'view', 'edit' ),
     1060                                                                'properties' => array(
     1061                                                                        'visible' => array(
     1062                                                                                'type'    => 'string',
     1063                                                                                'context' => array( 'view', 'edit' ),
     1064                                                                        ),
     1065                                                                        'hidden'  => array(
     1066                                                                                'type'    => 'string',
     1067                                                                                'context' => array( 'edit' ),
     1068                                                                        ),
     1069                                                                ),
     1070                                                        ),
     1071                                                ),
     1072                                        ),
     1073                                ),
     1074                                array(
     1075                                        'arr' => array(
     1076                                                array(
     1077                                                        'visible' => 'hi',
     1078                                                        'hidden'  => 'there',
     1079                                                ),
     1080                                        ),
     1081                                ),
     1082                                array( 'arr' => array( array( 'visible' => 'hi' ) ) ),
     1083                        ),
     1084                        'additional properties'  => array(
     1085                                array(
     1086                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     1087                                        'type'       => 'object',
     1088                                        'properties' => array(
     1089                                                'additional' => array(
     1090                                                        'type'                 => 'object',
     1091                                                        'context'              => array( 'view', 'edit' ),
     1092                                                        'properties'           => array(
     1093                                                                'a' => array(
     1094                                                                        'type'    => 'string',
     1095                                                                        'context' => array( 'view', 'edit' ),
     1096                                                                ),
     1097                                                                'b' => array(
     1098                                                                        'type'    => 'string',
     1099                                                                        'context' => array( 'edit' ),
     1100                                                                ),
     1101                                                        ),
     1102                                                        'additionalProperties' => array(
     1103                                                                'type'    => 'string',
     1104                                                                'context' => array( 'edit' ),
     1105                                                        ),
     1106                                                ),
     1107                                        ),
     1108                                ),
     1109                                array(
     1110                                        'additional' => array(
     1111                                                'a' => '1',
     1112                                                'b' => '2',
     1113                                                'c' => '3',
     1114                                        ),
     1115                                ),
     1116                                array( 'additional' => array( 'a' => '1' ) ),
     1117                        ),
     1118                        'multiple types object'  => array(
     1119                                array(
     1120                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     1121                                        'type'       => 'object',
     1122                                        'properties' => array(
     1123                                                'multi' => array(
     1124                                                        'type'       => array( 'object', 'string' ),
     1125                                                        'context'    => array( 'view', 'edit' ),
     1126                                                        'properties' => array(
     1127                                                                'a' => array(
     1128                                                                        'type'    => 'string',
     1129                                                                        'context' => array( 'view', 'edit' ),
     1130                                                                ),
     1131                                                                'b' => array(
     1132                                                                        'type'    => 'string',
     1133                                                                        'context' => array( 'edit' ),
     1134                                                                ),
     1135                                                        ),
     1136                                                ),
     1137                                        ),
     1138                                ),
     1139                                array(
     1140                                        'multi' => array(
     1141                                                'a' => '1',
     1142                                                'b' => '2',
     1143                                        ),
     1144                                ),
     1145                                array( 'multi' => array( 'a' => '1' ) ),
     1146                        ),
     1147                        'multiple types array'   => array(
     1148                                array(
     1149                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     1150                                        'type'       => 'object',
     1151                                        'properties' => array(
     1152                                                'multi' => array(
     1153                                                        'type'    => array( 'array', 'string' ),
     1154                                                        'context' => array( 'view', 'edit' ),
     1155                                                        'items'   => array(
     1156                                                                'type'       => 'object',
     1157                                                                'context'    => array( 'view', 'edit' ),
     1158                                                                'properties' => array(
     1159                                                                        'visible' => array(
     1160                                                                                'type'    => 'string',
     1161                                                                                'context' => array( 'view', 'edit' ),
     1162                                                                        ),
     1163                                                                        'hidden'  => array(
     1164                                                                                'type'    => 'string',
     1165                                                                                'context' => array( 'edit' ),
     1166                                                                        ),
     1167                                                                ),
     1168                                                        ),
     1169                                                ),
     1170                                        ),
     1171                                ),
     1172                                array(
     1173                                        'multi' => array(
     1174                                                array(
     1175                                                        'visible' => '1',
     1176                                                        'hidden'  => '2',
     1177                                                ),
     1178                                        ),
     1179                                ),
     1180                                array( 'multi' => array( array( 'visible' => '1' ) ) ),
     1181                        ),
     1182                        'grand child properties traverses missing context' => array(
     1183                                array(
     1184                                        '$schema'    => 'http://json-schema.org/draft-04/schema#',
     1185                                        'type'       => 'object',
     1186                                        'properties' => array(
     1187                                                'parent' => array(
     1188                                                        'type'       => 'object',
     1189                                                        'context'    => array( 'view', 'edit' ),
     1190                                                        'properties' => array(
     1191                                                                'child' => array(
     1192                                                                        'type'       => 'object',
     1193                                                                        'properties' => array(
     1194                                                                                'grand'  => array(
     1195                                                                                        'type'    => 'string',
     1196                                                                                        'context' => array( 'view', 'edit' ),
     1197                                                                                ),
     1198                                                                                'hidden' => array(
     1199                                                                                        'type'    => 'string',
     1200                                                                                        'context' => array( 'edit' ),
     1201                                                                                ),
     1202                                                                        ),
     1203                                                                ),
     1204                                                        ),
     1205                                                ),
     1206                                        ),
     1207                                ),
     1208                                array(
     1209                                        'parent' => array(
     1210                                                'child' => array(
     1211                                                        'grand' => 'hi',
     1212                                                ),
     1213                                        ),
     1214                                ),
     1215                                array( 'parent' => array( 'child' => array( 'grand' => 'hi' ) ) ),
     1216                        ),
     1217                );
     1218        }
    9091219}