Skip to:
Content

BuddyPress.org

Ticket #7156: 7156.3.patch

File 7156.3.patch, 22.7 KB (added by imath, 5 years ago)
  • Gruntfile.js

    diff --git Gruntfile.js Gruntfile.js
    index 061724429..542ac1a6f 100644
    module.exports = function( grunt ) { 
    190190                        }
    191191                },
    192192                clean: {
    193                         all: [ BUILD_DIR ]
     193                        all: [ BUILD_DIR ],
     194                        bp_rest: [ BUILD_DIR + 'bp-rest/' ]
    194195                },
    195196                copy: {
    196197                        files: {
    module.exports = function( grunt ) { 
    209210                                                src: ['composer.json']
    210211                                        }
    211212                                ]
     213                        },
     214                        bp_rest_components: {
     215                                cwd: BUILD_DIR + 'bp-rest/includes/',
     216                                dest: BUILD_DIR,
     217                                dot: true,
     218                                expand: true,
     219                                src: ['**/bp-activity/**', '**/bp-blogs/**', '**/bp-friends/**', '**/bp-groups/**', '**/bp-members/**', '**/bp-messages/**', '**/bp-notifications/**', '**/bp-settings/**', '**/bp-xprofile/**'],
     220                                options: {
     221                                        process : function( content ) {
     222                                                return content.replace( /\@since 0\.1\.0/g, '@since 5.0.0' );
     223                                        }
     224                                }
     225                        },
     226                        bp_rest_core: {
     227                                cwd: BUILD_DIR + 'bp-rest/includes/',
     228                                dest: BUILD_DIR + 'bp-core/classes/',
     229                                dot: true,
     230                                expand: true,
     231                                flatten: true,
     232                                filter: 'isFile',
     233                                src: ['**', '!functions.php', '!**/bp-activity/**', '!**/bp-blogs/**', '!**/bp-friends/**', '!**/bp-groups/**', '!**/bp-members/**', '!**/bp-messages/**', '!**/bp-notifications/**', '!**/bp-settings/**', '!**/bp-xprofile/**'],
     234                                options: {
     235                                        process : function( content ) {
     236                                                return content.replace( /\@since 0\.1\.0/g, '@since 5.0.0' );
     237                                        }
     238                                }
    212239                        }
    213240                },
    214241                uglify: {
    module.exports = function( grunt ) { 
    300327                        phpcompat: {
    301328                                command: './vendor/bin/phpcs -p --standard=PHPCompatibilityWP --extensions=php --runtime-set testVersion 5.3- src tests',
    302329                                stdout: true
     330                        },
     331                        rest_api: {
     332                                command: 'svn export --force https://github.com/buddypress/BP-REST.git/trunk bp-rest',
     333                                cwd: BUILD_DIR,
     334                                stdout: false
    303335                        }
    304336                },
    305337                jsvalidate:{
    module.exports = function( grunt ) { 
    331363                }
    332364        });
    333365
    334 
    335366        /**
    336367         * Register tasks.
    337368         */
    338369        grunt.registerTask( 'src',     ['checkDependencies', 'jsvalidate:src', 'jshint', 'stylelint', 'sass', 'postcss', 'rtlcss'] );
    339370        grunt.registerTask( 'commit',  ['src', 'checktextdomain', 'imagemin', 'phplint', 'exec:phpcompat'] );
    340         grunt.registerTask( 'build',   ['commit', 'clean:all', 'copy:files', 'uglify', 'jsvalidate:build', 'cssmin', 'makepot', 'exec:bpdefault', 'exec:cli'] );
     371        grunt.registerTask( 'bp_rest', [ 'exec:rest_api', 'copy:bp_rest_components', 'copy:bp_rest_core', 'clean:bp_rest' ] );
     372        grunt.registerTask( 'build',   ['commit', 'clean:all', 'copy:files', 'uglify', 'jsvalidate:build', 'cssmin', 'bp_rest', 'makepot', 'exec:bpdefault', 'exec:cli'] );
    341373        grunt.registerTask( 'release', ['build'] );
    342374
    343375        // Testing tasks.
  • src/bp-activity/classes/class-bp-activity-component.php

    diff --git src/bp-activity/classes/class-bp-activity-component.php src/bp-activity/classes/class-bp-activity-component.php
    index 1d882f213..a362a358c 100644
    class BP_Activity_Component extends BP_Component { 
    456456
    457457                parent::setup_cache_groups();
    458458        }
     459
     460        /**
     461         * Init the BP REST API.
     462         *
     463         * @since 5.0.0
     464         */
     465        public function rest_api_init() {
     466                $controller = new BP_REST_Activity_Endpoint();
     467                $controller->register_routes();
     468
     469                parent::rest_api_init();
     470        }
    459471}
  • src/bp-core/bp-core-rest-api.php

    diff --git src/bp-core/bp-core-rest-api.php src/bp-core/bp-core-rest-api.php
    index d4ad8319c..46ac80b00 100644
    function bp_rest_is_plugin_active() { 
    2121    return (bool) has_action( 'bp_rest_api_init', 'bp_rest', 5 );
    2222}
    2323
     24/**
     25 * Should we use the REST Endpoints of built BuddyPress?
     26 *
     27 * If the BP REST plugin is active, it overrides BuddyPress REST enpoints.
     28 * This allows us to carry on maintaining all the BP REST API endpoints from
     29 * the BP REST plugin on GitHub.
     30 *
     31 * @since 5.0.0
     32 *
     33 * @return bool Whether to use the REST Endpoints of built BuddyPress.
     34 */
     35function bp_rest_in_buddypress() {
     36    $is_src = defined( 'BP_SOURCE_SUBDIRECTORY' ) && BP_SOURCE_SUBDIRECTORY === 'src';
     37
     38    return ! $is_src && ! bp_rest_is_plugin_active();
     39}
     40
    2441/**
    2542 * Check the availability of the BP REST API.
    2643 *
    function bp_rest_is_plugin_active() { 
    2946 * @return boolean True if the BP REST API is available. False otherwise.
    3047 */
    3148function bp_rest_api_is_available() {
     49
    3250    /**
    3351     * Filter here to disable the BP REST API.
    3452     *
    function bp_rest_api_is_available() { 
    3856     *
    3957     * @param boolean $value True if the BP REST API is available. False otherwise.
    4058     */
    41     return apply_filters( 'bp_rest_api_is_available', function_exists( 'create_initial_rest_routes' ) && bp_rest_is_plugin_active() );
     59    return apply_filters( 'bp_rest_api_is_available', function_exists( 'create_initial_rest_routes' ) && bp_rest_in_buddypress() ) || bp_rest_is_plugin_active();
    4260}
    4361
    4462/**
    function bp_rest_api_register_request_script() { 
    7593    );
    7694}
    7795add_action( 'bp_init', 'bp_rest_api_register_request_script' );
     96
     97/**
     98 * BuddyPress REST API namespace.
     99 *
     100 * @since 5.0.0
     101 *
     102 * @return string
     103 */
     104function bp_rest_namespace() {
     105
     106        /**
     107         * Filter API namespace.
     108         *
     109         * @since 5.0.0
     110         *
     111         * @param string $namespace BuddyPress core namespace.
     112         */
     113        return apply_filters( 'bp_rest_namespace', 'buddypress' );
     114}
     115
     116/**
     117 * BuddyPress REST API version.
     118 *
     119 * @since 5.0.0
     120 *
     121 * @return string
     122 */
     123function bp_rest_version() {
     124
     125        /**
     126         * Filter API version.
     127         *
     128         * @since 5.0.0
     129         *
     130         * @param string $version BuddyPress core version.
     131         */
     132        return apply_filters( 'bp_rest_version', 'v1' );
     133}
     134
     135/**
     136 * Get user URL.
     137 *
     138 * @since 5.0.0
     139 *
     140 * @param  int $user_id User ID.
     141 * @return string
     142 */
     143function bp_rest_get_user_url( $user_id ) {
     144        return sprintf(
     145                '/%s/%s/members/%d',
     146                bp_rest_namespace(),
     147                bp_rest_version(),
     148                $user_id
     149        );
     150}
     151
     152/**
     153 * Set headers to let the Client Script be aware of the pagination.
     154 *
     155 * @since 5.0.0
     156 *
     157 * @param  WP_REST_Response $response The response data.
     158 * @param  integer          $total    The total number of found items.
     159 * @param  integer          $per_page The number of items per page of results.
     160 * @return WP_REST_Response $response The response data.
     161 */
     162function bp_rest_response_add_total_headers( WP_REST_Response $response, $total = 0, $per_page = 0 ) {
     163        if ( ! $total || ! $per_page ) {
     164                return $response;
     165        }
     166
     167        $total_items = (int) $total;
     168        $max_pages   = ceil( $total_items / (int) $per_page );
     169
     170        $response->header( 'X-WP-Total', $total_items );
     171        $response->header( 'X-WP-TotalPages', (int) $max_pages );
     172
     173        return $response;
     174}
     175
     176/**
     177 * Convert the input date to RFC3339 format.
     178 *
     179 * @since 5.0.0
     180 *
     181 * @param string      $date_gmt Date GMT format.
     182 * @param string|null $date     Optional. Date object.
     183 * @return string|null ISO8601/RFC3339 formatted datetime.
     184 */
     185function bp_rest_prepare_date_response( $date_gmt, $date = null ) {
     186        if ( isset( $date ) ) {
     187                return mysql_to_rfc3339( $date );
     188        }
     189
     190        if ( '0000-00-00 00:00:00' === $date_gmt ) {
     191                return null;
     192        }
     193
     194        return mysql_to_rfc3339( $date_gmt );
     195}
     196
     197/**
     198 * Clean up member_type input.
     199 *
     200 * @since 5.0.0
     201 *
     202 * @param string $value Comma-separated list of group types.
     203 * @return array|null
     204 */
     205function bp_rest_sanitize_member_types( $value ) {
     206        if ( empty( $value ) ) {
     207                return $value;
     208        }
     209
     210        $types              = explode( ',', $value );
     211        $registered_types   = bp_get_member_types();
     212        $registered_types[] = 'any';
     213        $valid_types        = array_intersect( $types, $registered_types );
     214
     215        return ( ! empty( $valid_types ) ) ? $valid_types : null;
     216}
     217
     218/**
     219 * Validate member_type input.
     220 *
     221 * @since 5.0.0
     222 *
     223 * @param  mixed $value Mixed value.
     224 * @return WP_Error|boolean
     225 */
     226function bp_rest_validate_member_types( $value ) {
     227        if ( empty( $value ) ) {
     228                return true;
     229        }
     230
     231        $types            = explode( ',', $value );
     232        $registered_types = bp_get_member_types();
     233
     234        // Add the special value.
     235        $registered_types[] = 'any';
     236        foreach ( $types as $type ) {
     237                if ( ! in_array( $type, $registered_types, true ) ) {
     238                        return new WP_Error(
     239                                'bp_rest_invalid_group_type',
     240                                sprintf(
     241                                        /* translators: %1$s and %2$s is replaced with the registered type(s) */
     242                                        __( 'The member type you provided, %$1s, is not one of %$2s.', 'buddypress' ),
     243                                        $type,
     244                                        implode( ', ', $registered_types )
     245                                )
     246                        );
     247                }
     248        }
     249}
     250
     251/**
     252 * Clean up group_type input.
     253 *
     254 * @since 5.0.0
     255 *
     256 * @param string $value Comma-separated list of group types.
     257 * @return array|null
     258 */
     259function bp_rest_sanitize_group_types( $value ) {
     260        if ( empty( $value ) ) {
     261                return null;
     262        }
     263
     264        $types       = explode( ',', $value );
     265        $valid_types = array_intersect( $types, bp_groups_get_group_types() );
     266
     267        return empty( $valid_types ) ? null : $valid_types;
     268}
     269
     270/**
     271 * Validate group_type input.
     272 *
     273 * @since 5.0.0
     274 *
     275 * @param  mixed $value Mixed value.
     276 * @return WP_Error|bool
     277 */
     278function bp_rest_validate_group_types( $value ) {
     279        if ( empty( $value ) ) {
     280                return true;
     281        }
     282
     283        $types            = explode( ',', $value );
     284        $registered_types = bp_groups_get_group_types();
     285        foreach ( $types as $type ) {
     286                if ( ! in_array( $type, $registered_types, true ) ) {
     287                        return new WP_Error(
     288                                'bp_rest_invalid_group_type',
     289                                sprintf(
     290                                        /* translators: %1$s and %2$s is replaced with the registered types */
     291                                        __( 'The group type you provided, %1$s, is not one of %2$s.', 'buddypress' ),
     292                                        $type,
     293                                        implode( ', ', $registered_types )
     294                                )
     295                        );
     296                }
     297        }
     298}
     299
     300/**
     301 * Clean up an array, comma- or space-separated list of strings.
     302 *
     303 * @since 5.0.0
     304 *
     305 * @param array|string $list List of strings.
     306 * @return array Sanitized array of strings.
     307 */
     308function bp_rest_sanitize_string_list( $list ) {
     309        if ( ! is_array( $list ) ) {
     310                $list = preg_split( '/[\s,]+/', $list );
     311        }
     312
     313        return array_unique( array_map( 'sanitize_text_field', $list ) );
     314}
     315
     316/**
     317 * Get the user object, if the ID is valid.
     318 *
     319 * @since 5.0.0
     320 *
     321 * @param int $user_id Supplied user ID.
     322 * @return WP_User|boolean
     323 */
     324function bp_rest_get_user( $user_id ) {
     325        if ( (int) $user_id <= 0 ) {
     326                return false;
     327        }
     328
     329        $user = get_userdata( (int) $user_id );
     330        if ( empty( $user ) || ! $user->exists() ) {
     331                return false;
     332        }
     333
     334        return $user;
     335}
     336
     337/**
     338 * Registers a new field on an existing BuddyPress object.
     339 *
     340 * @since 5.0.0
     341 *
     342 * @param string $component_id The name of the *active* component (eg: `activity`, `groups`, `xprofile`).
     343 *                             Required.
     344 * @param string $attribute    The attribute name. Required.
     345 * @param array  $args {
     346 *     Optional. An array of arguments used to handle the registered field.
     347 *     @see `register_rest_field()` for a full description.
     348 * }
     349 * @param string $object_type  The xProfile object type to get. This parameter is only required for
     350 *                             the Extended Profiles component. Not used for all other components.
     351 *                             Possible values are `data`, `field` or `group`.
     352 * @return bool                True if the field has been registered successfully. False otherwise.
     353 */
     354function bp_rest_register_field( $component_id, $attribute, $args = array(), $object_type = '' ) {
     355        $registered_fields = false;
     356
     357        if ( ! $component_id || ! bp_is_active( $component_id ) || ! $attribute ) {
     358                return $registered_fields;
     359        }
     360
     361        // Use the `bp_` prefix as we're using a WordPress global used for Post Types.
     362        $field_name = 'bp_' . $component_id;
     363
     364        // Use the meta type as a suffix for the field name.
     365        if ( 'xprofile' === $component_id ) {
     366                if ( ! in_array( $object_type, array( 'data', 'field', 'group' ), true ) ) {
     367                        return $registered_fields;
     368                }
     369
     370                $field_name .= '_' . $object_type;
     371        }
     372
     373        $args = bp_parse_args(
     374                $args,
     375                array(
     376                        'get_callback'    => null,
     377                        'update_callback' => null,
     378                        'schema'          => null,
     379                ),
     380                'rest_register_field'
     381        );
     382
     383        // Register the field.
     384        register_rest_field( $field_name, $attribute, $args );
     385
     386        if ( isset( $GLOBALS['wp_rest_additional_fields'][ $field_name ] ) ) {
     387                $registered_fields = $GLOBALS['wp_rest_additional_fields'][ $field_name ];
     388        }
     389
     390        // Check it has been registered.
     391        return isset( $registered_fields[ $attribute ] );
     392}
  • src/bp-core/classes/class-bp-component.php

    diff --git src/bp-core/classes/class-bp-component.php src/bp-core/classes/class-bp-component.php
    index 4802bf07f..7bed39f9e 100644
    class BP_Component { 
    461461                // Generate rewrite rules.
    462462                add_action( 'bp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10 );
    463463
     464                // Register BP REST Endpoints
     465                if ( bp_rest_in_buddypress() && bp_rest_api_is_available() ) {
     466                        add_action( 'bp_rest_api_init', array( $this, 'rest_api_init' ), 10 );
     467                }
     468
    464469                /**
    465470                 * Fires at the end of the setup_actions method inside BP_Component.
    466471                 *
    class BP_Component { 
    857862                 */
    858863                do_action( 'bp_' . $this->id . '_generate_rewrite_rules' );
    859864        }
     865
     866        /**
     867         * Init the BP REST API.
     868         *
     869         * @since 5.0.0
     870         */
     871        public function rest_api_init() {
     872
     873                /**
     874                 * Fires in the rest_api_init method inside BP_Component.
     875                 *
     876                 * This is a dynamic hook that is based on the component string ID.
     877                 *
     878                 * @since 5.0.0
     879                 */
     880                do_action( 'bp_' . $this->id . '_rest_api_init' );
     881        }
    860882}
    861883endif; // BP_Component.
  • src/bp-groups/classes/class-bp-groups-component.php

    diff --git src/bp-groups/classes/class-bp-groups-component.php src/bp-groups/classes/class-bp-groups-component.php
    index 8953c1062..296c4833a 100644
    class BP_Groups_Component extends BP_Component { 
    922922                        'public' => false,
    923923                ) );
    924924        }
     925
     926        /**
     927         * Init the BP REST API.
     928         *
     929         * @since 5.0.0
     930         */
     931        public function rest_api_init() {
     932                $controller = new BP_REST_Groups_Endpoint();
     933                $controller->register_routes();
     934
     935                $controller = new BP_REST_Group_Membership_Endpoint();
     936                $controller->register_routes();
     937
     938                $controller = new BP_REST_Group_Invites_Endpoint();
     939                $controller->register_routes();
     940
     941                $controller = new BP_REST_Group_Membership_Request_Endpoint();
     942                $controller->register_routes();
     943
     944                $controller = new BP_REST_Attachments_Group_Avatar_Endpoint();
     945                $controller->register_routes();
     946
     947                parent::rest_api_init();
     948        }
    925949}
  • src/bp-members/classes/class-bp-members-component.php

    diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php
    index 20c3eccee..4b1647976 100644
    class BP_Members_Component extends BP_Component { 
    456456
    457457                parent::setup_cache_groups();
    458458        }
     459
     460        /**
     461         * Init the BP REST API.
     462         *
     463         * @since 5.0.0
     464         */
     465        public function rest_api_init() {
     466                /**
     467                 * As the Members component is always loaded,
     468                 * let's register the Components endpoint here.
     469                 */
     470                $controller = new BP_REST_Components_Endpoint();
     471                $controller->register_routes();
     472
     473                $controller = new BP_REST_Members_Endpoint();
     474                $controller->register_routes();
     475
     476                $controller = new BP_REST_Attachments_Member_Avatar_Endpoint();
     477                $controller->register_routes();
     478
     479                parent::rest_api_init();
     480        }
    459481}
  • src/bp-messages/classes/class-bp-messages-component.php

    diff --git src/bp-messages/classes/class-bp-messages-component.php src/bp-messages/classes/class-bp-messages-component.php
    index b9ccc35ee..3062d5c5d 100644
    class BP_Messages_Component extends BP_Component { 
    433433
    434434                parent::setup_cache_groups();
    435435        }
     436
     437        /**
     438         * Init the BP REST API.
     439         *
     440         * @since 5.0.0
     441         */
     442        public function rest_api_init() {
     443                $controller = new BP_REST_Messages_Endpoint();
     444                $controller->register_routes();
     445
     446                parent::rest_api_init();
     447        }
    436448}
  • src/bp-notifications/classes/class-bp-notifications-component.php

    diff --git src/bp-notifications/classes/class-bp-notifications-component.php src/bp-notifications/classes/class-bp-notifications-component.php
    index 52716bfe8..2eaaba415 100644
    class BP_Notifications_Component extends BP_Component { 
    315315
    316316                parent::setup_cache_groups();
    317317        }
     318
     319        /**
     320         * Init the BP REST API.
     321         *
     322         * @since 5.0.0
     323         */
     324        public function rest_api_init() {
     325                $controller = new BP_REST_Notifications_Endpoint();
     326                $controller->register_routes();
     327
     328                parent::rest_api_init();
     329        }
    318330}
  • src/bp-xprofile/classes/class-bp-xprofile-component.php

    diff --git src/bp-xprofile/classes/class-bp-xprofile-component.php src/bp-xprofile/classes/class-bp-xprofile-component.php
    index 8b619afc9..3ade404aa 100644
    class BP_XProfile_Component extends BP_Component { 
    489489
    490490                return $wp_admin_nav;
    491491        }
     492
     493        /**
     494         * Init the BP REST API.
     495         *
     496         * @since 5.0.0
     497         */
     498        public function rest_api_init() {
     499                $controller = new BP_REST_XProfile_Fields_Endpoint();
     500                $controller->register_routes();
     501
     502                $controller = new BP_REST_XProfile_Field_Groups_Endpoint();
     503                $controller->register_routes();
     504
     505                $controller = new BP_REST_XProfile_Data_Endpoint();
     506                $controller->register_routes();
     507
     508                parent::rest_api_init();
     509        }
    492510}
  • src/class-buddypress.php

    diff --git src/class-buddypress.php src/class-buddypress.php
    index b5e6ef4a9..c3639b7d9 100644
    class BuddyPress { 
    545545
    546546                // These classes don't have a name that matches their component.
    547547                $irregular_map = array(
    548                         'BP_Akismet' => 'activity',
    549 
    550                         'BP_Admin'                     => 'core',
    551                         'BP_Attachment_Avatar'         => 'core',
    552                         'BP_Attachment_Cover_Image'    => 'core',
    553                         'BP_Attachment'                => 'core',
    554                         'BP_Button'                    => 'core',
    555                         'BP_Component'                 => 'core',
    556                         'BP_Customizer_Control_Range'  => 'core',
    557                         'BP_Date_Query'                => 'core',
    558                         'BP_Email_Delivery'            => 'core',
    559                         'BP_Email_Address'             => 'core',
    560                         'BP_Email_Recipient'           => 'core',
    561                         'BP_Email_Sender'              => 'core',
    562                         'BP_Email_Participant'         => 'core',
    563                         'BP_Email'                     => 'core',
    564                         'BP_Embed'                     => 'core',
    565                         'BP_Media_Extractor'           => 'core',
    566                         'BP_Members_Suggestions'       => 'core',
    567                         'BP_PHPMailer'                 => 'core',
    568                         'BP_Recursive_Query'           => 'core',
    569                         'BP_Suggestions'               => 'core',
    570                         'BP_Theme_Compat'              => 'core',
    571                         'BP_User_Query'                => 'core',
    572                         'BP_Walker_Category_Checklist' => 'core',
    573                         'BP_Walker_Nav_Menu_Checklist' => 'core',
    574                         'BP_Walker_Nav_Menu'           => 'core',
    575                         'BP_Invitation_Manager'        => 'core',
    576                         'BP_Invitation'                => 'core',
     548                        'BP_Akismet'                => 'activity',
     549                        'BP_REST_Activity_Endpoint' => 'activity',
     550
     551                        'BP_Admin'                                   => 'core',
     552                        'BP_Attachment_Avatar'                       => 'core',
     553                        'BP_Attachment_Cover_Image'                  => 'core',
     554                        'BP_Attachment'                              => 'core',
     555                        'BP_Button'                                  => 'core',
     556                        'BP_Component'                               => 'core',
     557                        'BP_Customizer_Control_Range'                => 'core',
     558                        'BP_Date_Query'                              => 'core',
     559                        'BP_Email_Delivery'                          => 'core',
     560                        'BP_Email_Address'                           => 'core',
     561                        'BP_Email_Recipient'                         => 'core',
     562                        'BP_Email_Sender'                            => 'core',
     563                        'BP_Email_Participant'                       => 'core',
     564                        'BP_Email'                                   => 'core',
     565                        'BP_Embed'                                   => 'core',
     566                        'BP_Media_Extractor'                         => 'core',
     567                        'BP_Members_Suggestions'                     => 'core',
     568                        'BP_PHPMailer'                               => 'core',
     569                        'BP_Recursive_Query'                         => 'core',
     570                        'BP_Suggestions'                             => 'core',
     571                        'BP_Theme_Compat'                            => 'core',
     572                        'BP_User_Query'                              => 'core',
     573                        'BP_Walker_Category_Checklist'               => 'core',
     574                        'BP_Walker_Nav_Menu_Checklist'               => 'core',
     575                        'BP_Walker_Nav_Menu'                         => 'core',
     576                        'BP_Invitation_Manager'                      => 'core',
     577                        'BP_Invitation'                              => 'core',
     578                        'BP_REST_Components_Endpoint'                => 'core',
     579                        'BP_REST_Attachments'                        => 'core',
     580                        'BP_REST_Attachments_Member_Avatar_Endpoint' => 'core',
     581                        'BP_REST_Attachments_Group_Avatar_Endpoint'  => 'core',
    577582
    578583                        'BP_Core_Friends_Widget' => 'friends',
    579584
    580                         'BP_Group_Extension'    => 'groups',
    581                         'BP_Group_Member_Query' => 'groups',
     585                        'BP_Group_Extension'                        => 'groups',
     586                        'BP_Group_Member_Query'                     => 'groups',
     587                        'BP_REST_Groups_Endpoint'                   => 'groups',
     588                        'BP_REST_Group_Membership_Endpoint'         => 'groups',
     589                        'BP_REST_Group_Invites_Endpoint'            => 'groups',
     590                        'BP_REST_Group_Membership_Request_Endpoint' => 'groups',
    582591
    583592                        'BP_Core_Members_Template'       => 'members',
    584593                        'BP_Core_Members_Widget'         => 'members',
    class BuddyPress { 
    586595                        'BP_Core_Whos_Online_Widget'     => 'members',
    587596                        'BP_Registration_Theme_Compat'   => 'members',
    588597                        'BP_Signup'                      => 'members',
     598                        'BP_REST_Members_Endpoint'       => 'members',
     599
     600                        'BP_REST_Messages_Endpoint' => 'messages',
     601
     602                        'BP_REST_Notifications_Endpoint' => 'notifications',
     603
     604                        'BP_REST_XProfile_Fields_Endpoint'       => 'xprofile',
     605                        'BP_REST_XProfile_Field_Groups_Endpoint' => 'xprofile',
     606                        'BP_REST_XProfile_Data_Endpoint'         => 'xprofile',
    589607                );
    590608
    591609                $component = null;
    class BuddyPress { 
    606624                // Sanitize class name.
    607625                $class = strtolower( str_replace( '_', '-', $class ) );
    608626
    609                 $path = dirname( __FILE__ ) . "/bp-{$component}/classes/class-{$class}.php";
     627                if ( 'bp-rest-attachments' === $class ) {
     628                        $path = dirname( __FILE__ ) . "/bp-{$component}/classes/trait-attachments.php";
     629                } else {
     630                        $path = dirname( __FILE__ ) . "/bp-{$component}/classes/class-{$class}.php";
     631                }
    610632
    611633                // Sanity check.
    612634                if ( ! file_exists( $path ) ) {
  • tests/phpunit/includes/testcase.php

    diff --git tests/phpunit/includes/testcase.php tests/phpunit/includes/testcase.php
    index 1b5022ec4..1428a6e17 100644
    class BP_UnitTestCase extends WP_UnitTestCase { 
    324324                        $_SERVER['SERVER_NAME'] = self::$cached_SERVER_NAME;
    325325                        self::$cached_SERVER_NAME = '';
    326326                } else {
    327                         unset( $_SERVER['SERVER_NAME'] );
     327                        $_SERVER['SERVER_NAME'] = WP_TESTS_DOMAIN;
    328328                }
    329329
    330330                // passthrough