[
  {
    "path": ".distignore",
    "content": ".DS_Store\n.git\n.gitignore\n.gitlab-ci.yml\n.editorconfig\n.travis.yml\nbehat.yml\ncircle.yml\nbin/\nfeatures/\nutils/\n*.zip\n*.tar.gz\n"
  },
  {
    "path": ".editorconfig",
    "content": "# This file is for unifying the coding style for different editors and IDEs\n# editorconfig.org\n\n# WordPress Coding Standards\n# https://make.wordpress.org/core/handbook/coding-standards/\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_style = tab\n\n[*.yml]\nindent_style = space\nindent_size = 2\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[{*.txt}]\nend_of_line = crlf\n"
  },
  {
    "path": ".gitignore",
    "content": "# Files and folders related to build/test tools\n/phpunit.xml\n/node_modules\n/npm-debug.log\n/vendor/\n.vscode\n.wp-env.override.json\ncomposer.lock\n.phpunit.result.cache\n\n# Operating system specific files\n.DS_Store\n\n# Cache files\n.phpcs/*.json\n"
  },
  {
    "path": ".phpcs/.gitkeep",
    "content": "# This directory can't be empty.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\nHi, and thanks for considering contributing! Before you do though, here's a few\nnotes on how best to contribute. Don't worry, I'll keep it short!\n\n## Best Practices\n\n### Commit Messages\nCommit messages should follow the standard laid out in the git manual; that is,\na one-line summary ()\n\n\tShort (50 chars or less) summary of changes\n\n\tMore detailed explanatory text, if necessary.  Wrap it to about 72\n\tcharacters or so.  In some contexts, the first line is treated as the\n\tsubject of an email and the rest of the text as the body.  The blank\n\tline separating the summary from the body is critical (unless you omit\n\tthe body entirely); tools like rebase can get confused if you run the\n\ttwo together.\n\n\tFurther paragraphs come after blank lines.\n\n\t - Bullet points are okay, too\n\n\t - Typically a hyphen or asterisk is used for the bullet, preceded by a\n\t   single space, with blank lines in between, but conventions vary here\n\n## Commit Process\nChanges are proposed in the form of pull requests by you, the contributor! After\nsubmitting your proposed changes, a member of the API team will review your\ncommits and mark them for merge by assigning it to themselves. Your pull request\nwill then be merged after final review by another member.\n\n## Unit tests\nIt's important the code submitted comes with proper unit tests and comply with the WordPress Coding Standards.\n"
  },
  {
    "path": "README.md",
    "content": "# BuddyPress RESTful API\n\n[![Project Status: Active.](https://www.repostatus.org/badges/latest/inactive.svg)](https://www.repostatus.org/#inactive)\n\nAccess your BuddyPress site's data through an easy-to-use HTTP REST API.\n\n## Documentation\n\nThis plugin has been deprecated since the V2 of the BP REST API was introduced\nat [#9145](https://buddypress.trac.wordpress.org/ticket/9145) and is no longer maintained.\n"
  },
  {
    "path": "bp-rest.php",
    "content": "<?php\n/**\n * Plugin Name:       BuddyPress RESTful API (Deprecated)\n * Plugin URI:        https://buddypress.org\n * Description:       Access your BuddyPress site's data through an easy-to-use HTTP REST API.\n * Author:            The BuddyPress Community\n * Author URI:        https://buddypress.org/\n * Version:           0.9.0\n * Text Domain:       buddypress\n * Requires at least: 6.1\n * Tested up to:      6.7\n * Requires PHP:      5.6\n * Requires Plugins:  buddypress\n * License:           GNU General Public License v2 or later\n * License URI:       https://www.gnu.org/licenses/gpl-2.0.html\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\n/**\n * Copyright (c) 2020 BuddyPress (email: contact@buddypress.org)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License, version 2 or, at\n * your discretion, any later version, as published by the Free\n * Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Register BuddyPress endpoints.\n *\n * @since 0.1.0\n */\nfunction bp_rest() {\n\t// Bail early if no core rest support.\n\tif ( ! class_exists( 'WP_REST_Controller' ) ) {\n\t\treturn;\n\t}\n\n\trequire_once __DIR__ . '/includes/bp-components/classes/class-bp-rest-components-endpoint.php';\n\t$controller = new BP_REST_Components_Endpoint();\n\t$controller->register_routes();\n\n\tif ( bp_is_active( 'members' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-members/classes/class-bp-rest-members-endpoint.php';\n\t\t$controller = new BP_REST_Members_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-attachments/classes/trait-attachments.php';\n\n\t\t// Support Member's Avatar.\n\t\trequire_once __DIR__ . '/includes/bp-members/classes/class-bp-rest-attachments-member-avatar-endpoint.php';\n\t\t$controller = new BP_REST_Attachments_Member_Avatar_Endpoint();\n\t\t$controller->register_routes();\n\n\t\t// Support Member's Cover.\n\t\tif ( bp_is_active( 'members', 'cover_image' ) ) {\n\t\t\trequire_once __DIR__ . '/includes/bp-members/classes/class-bp-rest-attachments-member-cover-endpoint.php';\n\t\t\t$controller = new BP_REST_Attachments_Member_Cover_Endpoint();\n\t\t\t$controller->register_routes();\n\t\t}\n\n\t\tif ( bp_get_signup_allowed() ) {\n\t\t\trequire_once __DIR__ . '/includes/bp-members/classes/class-bp-rest-signup-endpoint.php';\n\t\t\t$controller = new BP_REST_Signup_Endpoint();\n\t\t\t$controller->register_routes();\n\t\t}\n\t}\n\n\tif ( bp_is_active( 'activity' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-activity/classes/class-bp-rest-activity-endpoint.php';\n\t\t$controller = new BP_REST_Activity_Endpoint();\n\t\t$controller->register_routes();\n\t}\n\n\tif ( is_multisite() && bp_is_active( 'blogs' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-blogs/classes/class-bp-rest-blogs-endpoint.php';\n\t\t$controller = new BP_REST_Blogs_Endpoint();\n\t\t$controller->register_routes();\n\n\t\t// Support to Blog Avatar.\n\t\tif ( bp_is_active( 'blogs', 'site-icon' ) ) {\n\t\t\trequire_once __DIR__ . '/includes/bp-attachments/classes/trait-attachments.php';\n\t\t\trequire_once __DIR__ . '/includes/bp-blogs/classes/class-bp-rest-attachments-blog-avatar-endpoint.php';\n\t\t\t$controller = new BP_REST_Attachments_Blog_Avatar_Endpoint();\n\t\t\t$controller->register_routes();\n\t\t}\n\t}\n\n\tif ( bp_is_active( 'xprofile' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-xprofile/classes/class-bp-rest-xprofile-fields-endpoint.php';\n\t\t$controller = new BP_REST_XProfile_Fields_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-xprofile/classes/class-bp-rest-xprofile-field-groups-endpoint.php';\n\t\t$controller = new BP_REST_XProfile_Field_Groups_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-xprofile/classes/class-bp-rest-xprofile-data-endpoint.php';\n\t\t$controller = new BP_REST_XProfile_Data_Endpoint();\n\t\t$controller->register_routes();\n\t}\n\n\tif ( bp_is_active( 'groups' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-groups/classes/class-bp-rest-groups-endpoint.php';\n\t\t$controller = new BP_REST_Groups_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-groups/classes/class-bp-rest-group-membership-endpoint.php';\n\t\t$controller = new BP_REST_Group_Membership_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-groups/classes/class-bp-rest-group-invites-endpoint.php';\n\t\t$controller = new BP_REST_Group_Invites_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-groups/classes/class-bp-rest-group-membership-request-endpoint.php';\n\t\t$controller = new BP_REST_Group_Membership_Request_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-attachments/classes/trait-attachments.php';\n\t\trequire_once __DIR__ . '/includes/bp-groups/classes/class-bp-rest-attachments-group-avatar-endpoint.php';\n\t\t$controller = new BP_REST_Attachments_Group_Avatar_Endpoint();\n\t\t$controller->register_routes();\n\n\t\t// Support to Group Cover.\n\t\tif ( bp_is_active( 'groups', 'cover_image' ) ) {\n\t\t\trequire_once __DIR__ . '/includes/bp-groups/classes/class-bp-rest-attachments-group-cover-endpoint.php';\n\t\t\t$controller = new BP_REST_Attachments_Group_Cover_Endpoint();\n\t\t\t$controller->register_routes();\n\t\t}\n\t}\n\n\tif ( bp_is_active( 'messages' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-messages/classes/class-bp-rest-messages-endpoint.php';\n\t\t$controller = new BP_REST_Messages_Endpoint();\n\t\t$controller->register_routes();\n\n\t\trequire_once __DIR__ . '/includes/bp-messages/classes/class-bp-rest-sitewide-notices-endpoint.php';\n\t\t$controller = new BP_REST_Sitewide_Notices_Endpoint();\n\t\t$controller->register_routes();\n\t}\n\n\tif ( bp_is_active( 'notifications' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-notifications/classes/class-bp-rest-notifications-endpoint.php';\n\t\t$controller = new BP_REST_Notifications_Endpoint();\n\t\t$controller->register_routes();\n\t}\n\n\tif ( bp_is_active( 'friends' ) ) {\n\t\trequire_once __DIR__ . '/includes/bp-friends/classes/class-bp-rest-friends-endpoint.php';\n\t\t$controller = new BP_REST_Friends_Endpoint();\n\t\t$controller->register_routes();\n\t}\n}\nadd_action( 'bp_rest_api_init', 'bp_rest', 5 );\n\n/**\n * Set the current BP REST namespace.\n *\n * @return string\n */\nfunction bp_filter_v1_rest_current_rest_namespace() {\n\treturn 'buddypress';\n}\nadd_filter( 'bp_rest_namespace', 'bp_filter_v1_rest_current_rest_namespace' );\n\n/**\n * Set the current BP REST version.\n *\n * @return string\n */\nfunction bp_filter_v1_rest_current_rest_version() {\n\treturn 'v1';\n}\nadd_filter( 'bp_rest_version', 'bp_filter_v1_rest_current_rest_version' );\n\n/**\n * Filter the Blog url in the WP_REST_Request::from_url().\n *\n * @param WP_REST_Request $request Request used to generate the response.\n * @param string          $url     URL being requested.\n * @return WP_REST_Request\n */\nfunction bp_filter_v1_rest_request_blog_url( $request, $url ) {\n\n\tif ( ! bp_is_active( 'blogs' ) || empty( $url ) ) {\n\t\treturn $request;\n\t}\n\n\t// Get url info.\n\t$bits      = wp_parse_url( $url );\n\t$home_bits = wp_parse_url( get_home_url() );\n\n\tif ( empty( $bits['host'] ) || empty( $home_bits['host'] ) ) {\n\t\treturn $request;\n\t}\n\n\t// Bail early if the request URL is the same as the current site.\n\tif ( $bits['host'] === $home_bits['host'] ) {\n\t\treturn $request;\n\t}\n\n\t// Create a fake request to bypass the current logic.\n\t$request = new WP_REST_Request( 'GET', $bits['path'] );\n\t$request->set_query_params( array( 'bp_blogs_url' => $url ) );\n\n\treturn $request;\n}\nadd_filter( 'rest_request_from_url', 'bp_filter_v1_rest_request_blog_url', 10, 2 );\n\n/**\n * Output BuddyPress blog response.\n *\n * @param WP_REST_Response $response Response generated by the request.\n * @param WP_REST_Server   $instance Server instance.\n * @param WP_REST_Request  $request  Request used to generate the response.\n * @return WP_REST_Response\n */\nfunction bp_filter_v1_rest_post_dispatch( $response, $instance, $request ) {\n\tif (\n\t\t! bp_is_active( 'blogs' )\n\t\t|| 404 !== $response->get_status()\n\t\t|| 'embed' !== $request->get_param( 'context' )\n\t\t|| empty( $request->get_param( 'bp_blogs_url' ) )\n\t\t|| empty( $request->get_route() )\n\t) {\n\t\treturn $response;\n\t}\n\n\t// Get domain from url.\n\t$bits = wp_parse_url( $request->get_param( 'bp_blogs_url' ) );\n\n\t// We need those two to proceed.\n\tif ( empty( $bits['host'] ) || empty( $bits['path'] ) ) {\n\t\treturn $response;\n\t}\n\n\t// Request route and requested URL path should match.\n\tif ( $request->get_route() !== $bits['path'] ) {\n\t\treturn $response;\n\t}\n\n\t// Get site using the domain.\n\t$site = get_site_by_path( $bits['host'], $bits['path'] );\n\n\tif ( ! $site instanceof WP_Site || empty( $site->blog_id ) ) {\n\t\treturn $response;\n\t}\n\n\tswitch_to_blog( absint( $site->blog_id ) );\n\n\t$response = rest_do_request(\n\t\tnew WP_REST_Request(\n\t\t\t'GET',\n\t\t\tstr_replace(\n\t\t\t\t'/wp-json',\n\t\t\t\t'',\n\t\t\t\t$request->get_route()\n\t\t\t)\n\t\t)\n\t);\n\n\trestore_current_blog();\n\n\t// Return it, regardless if it was successful or not.\n\treturn $response;\n}\nadd_filter( 'rest_post_dispatch', 'bp_filter_v1_rest_post_dispatch', 10, 3 );\n"
  },
  {
    "path": "composer.json",
    "content": "{\n\t\"name\": \"buddypress/bp-rest\",\n\t\"description\": \"Access your BuddyPress site's data through an easy-to-use HTTP REST API.\",\n\t\"type\": \"wordpress-plugin\",\n\t\"keywords\": [\n\t\t\"bp-rest\",\n\t\t\"bp-rest-api\",\n\t\t\"buddypress\",\n\t\t\"rest\",\n\t\t\"plugin\"\n\t],\n\t\"homepage\": \"https://buddypress.org\",\n\t\"license\": \"GPL-2.0-or-later\",\n\t\"authors\": [\n\t\t{\n\t\t\t\"name\": \"BuddyPress Community\",\n\t\t\t\"homepage\": \"https://buddypress.org/about/\"\n\t\t}\n\t],\n\t\"support\": {\n\t\t\"forum\": \"https://buddypress.org/support/\",\n\t\t\"docs\": \"https://codex.buddypress.org/\",\n\t\t\"issues\": \"https://buddypress.trac.wordpress.org/\",\n\t\t\"rss\": \"https://buddypress.org/feed/\",\n\t\t\"source\": \"https://buddypress.trac.wordpress.org/browser/\",\n\t\t\"wiki\": \"https://codex.buddypress.org/\"\n\t},\n\t\"config\": {\n\t\t\"archive-format\": \"zip\",\n\t\t\"allow-plugins\": {\n\t\t\t\"dealerdirect/phpcodesniffer-composer-installer\": true,\n\t\t\t\"composer/installers\": true\n\t\t}\n\t},\n\t\"require\": {\n\t\t\"php\": \">=5.6.0\"\n\t},\n\t\"require-dev\": {\n\t\t\"buddypress/bp-coding-standards\": \"dev-trunk\",\n\t\t\"yoast/phpunit-polyfills\": \"^1.0\"\n\t},\n\t\"scripts\": {\n\t\t\"test\": \"@php ./vendor/phpunit/phpunit/phpunit\",\n\t\t\"test_multi\": \"@php ./vendor/phpunit/phpunit/phpunit -c tests/multisite.xml\",\n\t\t\"phpunit\": \"@test\",\n\t\t\"phpcs\": \"@php ./vendor/bin/phpcs . --basepath=.\",\n\t\t\"phpcbf\": \"@php ./vendor/bin/phpcbf . --basepath=.\"\n\t},\n\t\"archive\": {\n\t\t\"exclude\": [\n\t\t\t\"*.xml\",\n\t\t\t\"*.dist\",\n\t\t\t\"*.cache\",\n\t\t\t\"phpcs.xml.dist\",\n\t\t\t\"phpunit.xml.dist\",\n\t\t\t\"wp-env.json\",\n\t\t\t\"composer.json\",\n\t\t\t\"composer.lock\",\n\t\t\t\"package.json\",\n\t\t\t\"package-lock.json\",\n\t\t\t\".editorconfig\",\n\t\t\t\"CHANGELOG.md\",\n\t\t\t\"CONTRIBUTING.md\",\n\t\t\t\"README.md\",\n\t\t\t\".gitignore\",\n\t\t\t\".distignore\",\n\t\t\t\".deployignore\",\n\t\t\t\".github/\",\n\t\t\t\".phpcs/\",\n\t\t\t\"tests/\",\n\t\t\t\"bp-rest-api.zip\",\n\t\t\t\"!vendor/\"\n\t\t]\n\t}\n}\n"
  },
  {
    "path": "includes/bp-activity/classes/class-bp-rest-activity-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Activity_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Activity endpoints.\n *\n * @since 0.1.0\n */\nclass BP_REST_Activity_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * User favorites.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var array|null\n\t */\n\tprotected $user_favorites = null;\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Activity_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = buddypress()->activity->id;\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\t$activity_endpoint = '/' . $this->rest_base . '/(?P<id>[\\d]+)';\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t$activity_endpoint,\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the activity.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'view' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\t// Register the favorite route.\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t$activity_endpoint . '/favorite',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the activity.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_favorite' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_favorite_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve activities.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response List of activities response data.\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'exclude'           => $request->get_param( 'exclude' ),\n\t\t\t'in'                => $request->get_param( 'include' ),\n\t\t\t'page'              => $request->get_param( 'page' ),\n\t\t\t'per_page'          => $request->get_param( 'per_page' ),\n\t\t\t'search_terms'      => $request->get_param( 'search' ),\n\t\t\t'sort'              => $request->get_param( 'order' ),\n\t\t\t'spam'              => $request->get_param( 'status' ),\n\t\t\t'display_comments'  => $request->get_param( 'display_comments' ),\n\t\t\t'site_id'           => $request->get_param( 'site_id' ),\n\t\t\t'group_id'          => $request->get_param( 'group_id' ),\n\t\t\t'scope'             => $request->get_param( 'scope' ),\n\t\t\t'count_total'       => true,\n\t\t\t'fields'            => 'all',\n\t\t\t'show_hidden'       => false,\n\t\t\t'update_meta_cache' => true,\n\t\t\t'filter'            => array(),\n\t\t);\n\n\t\tif ( empty( $args['display_comments'] ) || 'false' === $args['display_comments'] ) {\n\t\t\t$args['display_comments'] = false;\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'exclude' ) ) ) {\n\t\t\t$args['exclude'] = false;\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'include' ) ) ) {\n\t\t\t$args['in'] = false;\n\t\t}\n\n\t\tif ( ! empty( $request->get_param( 'after' ) ) ) {\n\t\t\t$args['since'] = $request->get_param( 'after' );\n\t\t}\n\n\t\tif ( ! empty( $request->get_param( 'user_id' ) ) ) {\n\t\t\t$args['filter']['user_id'] = $request->get_param( 'user_id' );\n\t\t}\n\n\t\t$item_id = 0;\n\t\tif ( ! empty( $args['group_id'] ) ) {\n\t\t\t$args['filter']['object']     = 'groups';\n\t\t\t$args['filter']['primary_id'] = $args['group_id'];\n\n\t\t\tif ( empty( $request->get_param( 'component' ) ) ) {\n\t\t\t\t$request->set_param( 'component', 'groups' );\n\t\t\t}\n\n\t\t\t$item_id = $args['group_id'];\n\t\t}\n\n\t\tif ( ! empty( $args['site_id'] ) ) {\n\t\t\t$args['filter']['object']     = 'blogs';\n\t\t\t$args['filter']['primary_id'] = $args['site_id'];\n\n\t\t\t$item_id = $args['site_id'];\n\t\t}\n\n\t\tif ( empty( $args['group_id'] ) && empty( $args['site_id'] ) ) {\n\t\t\tif ( ! empty( $request->get_param( 'component' ) ) ) {\n\t\t\t\t$args['filter']['object'] = $request->get_param( 'component' );\n\t\t\t}\n\n\t\t\tif ( ! empty( $request->get_param( 'primary_id' ) ) ) {\n\t\t\t\t$item_id                      = $request->get_param( 'primary_id' );\n\t\t\t\t$args['filter']['primary_id'] = $item_id;\n\t\t\t}\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'scope' ) ) ) {\n\t\t\t$args['scope'] = false;\n\t\t}\n\n\t\tif ( ! empty( $request->get_param( 'type' ) ) ) {\n\t\t\t$args['filter']['action'] = $request->get_param( 'type' );\n\t\t}\n\n\t\tif ( ! empty( $request->get_param( 'secondary_id' ) ) ) {\n\t\t\t$args['filter']['secondary_id'] = $request->get_param( 'secondary_id' );\n\t\t}\n\n\t\tif ( $args['in'] ) {\n\t\t\t$args['count_total'] = false;\n\t\t}\n\n\t\tif ( $this->show_hidden( $request->get_param( 'component' ), $item_id ) ) {\n\t\t\t$args['show_hidden'] = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request Full data about the request.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_activity_get_items_query_args', $args, $request );\n\n\t\t// Actually, query it.\n\t\t$activities = bp_activity_get( $args );\n\n\t\t$retval = array();\n\t\tforeach ( $activities['activities'] as $activity ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $activity, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $activities['total'], $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a list of activities is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $activities Fetched activities.\n\t\t * @param WP_REST_Response $response   The response data.\n\t\t * @param WP_REST_Request  $request    Full data about the request.\n\t\t */\n\t\tdo_action( 'bp_rest_activity_get_items', $activities, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to activity items.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'activity' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the activity `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request Full data about the request.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve an activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$activity = $this->get_activity_object( $request );\n\n\t\tif ( empty( $activity->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid activity ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $activity, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after an activity is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Activity_Activity $activity Fetched activity.\n\t\t * @param WP_REST_Response     $response The response data.\n\t\t * @param WP_REST_Request      $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_activity_get_item', $activity, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get information about a specific activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you cannot view the activities.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'activity' ) ) && $this->can_see( $request ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the activity `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Create an activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\tif ( empty( $request->get_param( 'content' ) ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_create_activity_empty_content',\n\t\t\t\t__( 'Please, enter some content.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 400,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$prepared_activity = $this->prepare_item_for_database( $request );\n\n\t\t// Fallback for the activity_update type.\n\t\t$type = 'activity_update';\n\t\tif ( ! empty( $request->get_param( 'type' ) ) ) {\n\t\t\t$type = $request->get_param( 'type' );\n\t\t}\n\n\t\t$prime       = $request->get_param( 'primary_item_id' );\n\t\t$activity_id = 0;\n\n\t\t// Post a regular activity update.\n\t\tif ( 'activity_update' === $type ) {\n\t\t\tif ( bp_is_active( 'groups' ) && ! is_null( $prime ) ) {\n\t\t\t\t$activity_id = groups_post_update( $prepared_activity );\n\t\t\t} else {\n\t\t\t\t$activity_id = bp_activity_post_update( $prepared_activity );\n\t\t\t}\n\n\t\t\t// Post an activity comment.\n\t\t} elseif ( 'activity_comment' === $type ) {\n\n\t\t\t// ID of the root activity item.\n\t\t\tif ( isset( $prime ) ) {\n\t\t\t\t$prepared_activity->activity_id = (int) $prime;\n\t\t\t}\n\n\t\t\t// ID of a parent comment.\n\t\t\tif ( ! empty( $request->get_param( 'secondary_item_id' ) ) ) {\n\t\t\t\t$prepared_activity->parent_id = $request->get_param( 'secondary_item_id' );\n\t\t\t}\n\n\t\t\t$activity_id = bp_activity_new_comment( $prepared_activity );\n\n\t\t\t// Otherwise add an activity.\n\t\t} else {\n\t\t\t$activity_id = bp_activity_add( $prepared_activity );\n\t\t}\n\n\t\tif ( ! is_numeric( $activity_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_create_activity',\n\t\t\t\t__( 'Cannot create new activity.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$activity = bp_activity_get(\n\t\t\tarray(\n\t\t\t\t'in'               => $activity_id,\n\t\t\t\t'display_comments' => 'stream',\n\t\t\t\t'show_hidden'      => true,\n\t\t\t)\n\t\t);\n\n\t\t$activity      = current( $activity['activities'] );\n\t\t$fields_update = $this->update_additional_fields_for_object( $activity, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t// Update current user's last activity.\n\t\tbp_update_user_last_activity();\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $activity, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after an activity item is created via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Activity_Activity $activity The created activity.\n\t\t * @param WP_REST_Response     $response The response data.\n\t\t * @param WP_REST_Request      $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_activity_create_item', $activity, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to create an activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$error = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to create activities.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\t$retval = $error;\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$user_id = $request->get_param( 'user_id' );\n\n\t\t\tif ( empty( $user_id ) || (int) bp_loggedin_user_id() === (int) $user_id ) {\n\t\t\t\t$item_id   = $request->get_param( 'primary_item_id' );\n\t\t\t\t$component = $request->get_param( 'component' );\n\n\t\t\t\t// The current user can create an activity.\n\t\t\t\t$retval = true;\n\n\t\t\t\tif ( bp_is_active( 'groups' ) && buddypress()->groups->id === $component && ! is_null( $item_id ) ) {\n\t\t\t\t\tif ( ! $this->show_hidden( $component, $item_id ) ) {\n\t\t\t\t\t\t$retval = $error;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the activity `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update an activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\tif ( empty( $request->get_param( 'content' ) ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_update_activity_empty_content',\n\t\t\t\t__( 'Please, enter some content.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 400,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$activity_id = bp_activity_add( $this->prepare_item_for_database( $request ) );\n\n\t\tif ( ! is_numeric( $activity_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_activity',\n\t\t\t\t__( 'Cannot update existing activity.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$activity      = $this->get_activity_object( $activity_id );\n\t\t$fields_update = $this->update_additional_fields_for_object( $activity, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $activity, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after an activity is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Activity_Activity $activity The updated activity.\n\t\t * @param WP_REST_Response     $response The response data.\n\t\t * @param WP_REST_Request      $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_activity_update_item', $activity, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update an activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to update this activity.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$activity = $this->get_activity_object( $request );\n\n\t\t\tif ( empty( $activity->id ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Invalid activity ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_activity_user_can_delete( $activity ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the activity `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the activity before it's deleted.\n\t\t$activity = $this->get_activity_object( $request );\n\t\t$previous = $this->prepare_item_for_response( $activity, $request );\n\n\t\tif ( 'activity_comment' === $activity->type ) {\n\t\t\t$retval = bp_activity_delete_comment( $activity->item_id, $activity->id );\n\t\t} else {\n\t\t\t$retval = bp_activity_delete(\n\t\t\t\tarray(\n\t\t\t\t\t'id' => $activity->id,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( ! $retval ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_activity_cannot_delete',\n\t\t\t\t__( 'Could not delete the activity.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after an activity is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Activity_Activity $activity The deleted activity.\n\t\t * @param WP_REST_Response     $response The response data.\n\t\t * @param WP_REST_Request      $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_activity_delete_item', $activity, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete an activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to delete this activity.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$activity = $this->get_activity_object( $request );\n\n\t\t\tif ( empty( $activity->id ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Invalid activity ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_activity_user_can_delete( $activity ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the activity `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Gets the current user's favorites.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array Array of activity IDs.\n\t */\n\tpublic function get_user_favorites() {\n\t\tif ( null === $this->user_favorites ) {\n\t\t\tif ( is_user_logged_in() ) {\n\t\t\t\t$user_favorites       = bp_activity_get_user_favorites( get_current_user_id() );\n\t\t\t\t$this->user_favorites = array_filter( wp_parse_id_list( $user_favorites ) );\n\t\t\t} else {\n\t\t\t\t$this->user_favorites = array();\n\t\t\t}\n\t\t}\n\n\t\treturn $this->user_favorites;\n\t}\n\n\t/**\n\t * Adds or removes the activity from the current user's favorites.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_favorite( $request ) {\n\t\t$activity = $this->get_activity_object( $request );\n\n\t\tif ( empty( $activity->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid activity ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$user_id = get_current_user_id();\n\n\t\t$result = false;\n\t\tif ( in_array( $activity->id, $this->get_user_favorites(), true ) ) {\n\t\t\t$result  = bp_activity_remove_user_favorite( $activity->id, $user_id );\n\t\t\t$message = __( 'Sorry, you cannot remove the activity from your favorites.', 'buddypress' );\n\n\t\t\t// Update the user favorites, removing the activity ID.\n\t\t\t$this->user_favorites = array_diff( $this->get_user_favorites(), array( $activity->id ) );\n\t\t} else {\n\t\t\t$result  = bp_activity_add_user_favorite( $activity->id, $user_id );\n\t\t\t$message = __( 'Sorry, you cannot add the activity to your favorites.', 'buddypress' );\n\n\t\t\t// Update the user favorites, adding the activity ID.\n\t\t\t$this->user_favorites[] = (int) $activity->id;\n\t\t}\n\n\t\tif ( ! $result ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_activity_favorite',\n\t\t\t\t$message,\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Prepare the response now the user favorites has been updated.\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $activity, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after user favorited activities has been updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Activity_Activity $activity       The updated activity.\n\t\t * @param array                $user_favorites The updated user favorites.\n\t\t * @param WP_REST_Response     $response       The response data.\n\t\t * @param WP_REST_Request      $request        The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_activity_update_favorite', $activity, $this->get_user_favorites(), $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update user favorites.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_favorite_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to update favorites.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() && bp_activity_can_favorite() && $this->can_see( $request ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the activity `update_favorite` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_update_favorite_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Renders the content of an activity.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Activity_Activity $activity Activity data.\n\t * @return string The rendered activity content.\n\t */\n\tpublic function render_item( $activity ) {\n\t\t$rendered = '';\n\n\t\tif ( empty( $activity->content ) ) {\n\t\t\treturn $rendered;\n\t\t}\n\n\t\t// Do not truncate activities.\n\t\tadd_filter( 'bp_activity_maybe_truncate_entry', '__return_false' );\n\n\t\tif ( 'activity_comment' === $activity->type ) {\n\t\t\t$rendered = apply_filters( 'bp_get_activity_content', $activity->content );\n\t\t} else {\n\t\t\t$activities_template = null;\n\n\t\t\tif ( isset( $GLOBALS['activities_template'] ) ) {\n\t\t\t\t$activities_template = $GLOBALS['activities_template'];\n\t\t\t}\n\n\t\t\t// Set the `activities_template` global for the current activity.\n\t\t\t$GLOBALS['activities_template']           = new stdClass();\n\t\t\t$GLOBALS['activities_template']->activity = $activity;\n\n\t\t\t// Set up activity oEmbed cache.\n\t\t\tbp_activity_embed();\n\n\t\t\t$rendered = apply_filters( 'bp_get_activity_content_body', $activity->content, $activity );\n\n\t\t\t// Restore the `activities_template` global.\n\t\t\t$GLOBALS['activities_template'] = $activities_template;\n\t\t}\n\n\t\t// Restore the filter to truncate activities.\n\t\tremove_filter( 'bp_activity_maybe_truncate_entry', '__return_false' );\n\n\t\treturn $rendered;\n\t}\n\n\t/**\n\t * Prepares activity data for return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Activity_Activity $activity Activity object.\n\t * @param WP_REST_Request      $request  Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $activity, $request ) {\n\t\t$data = array(\n\t\t\t'user_id'           => $activity->user_id,\n\t\t\t'component'         => $activity->component,\n\t\t\t'content'           => array(\n\t\t\t\t'raw'      => $activity->content,\n\t\t\t\t'rendered' => $this->render_item( $activity ),\n\t\t\t),\n\t\t\t'date'              => bp_rest_prepare_date_response( $activity->date_recorded, get_date_from_gmt( $activity->date_recorded ) ),\n\t\t\t'date_gmt'          => bp_rest_prepare_date_response( $activity->date_recorded ),\n\t\t\t'id'                => $activity->id,\n\t\t\t'link'              => bp_activity_get_permalink( $activity->id ),\n\t\t\t'primary_item_id'   => $activity->item_id,\n\t\t\t'secondary_item_id' => $activity->secondary_item_id,\n\t\t\t'status'            => $activity->is_spam ? 'spam' : 'published',\n\t\t\t'title'             => $activity->action,\n\t\t\t'type'              => $activity->type,\n\t\t\t'hidden'            => (bool) $activity->hide_sitewide,\n\t\t\t'favorited'         => in_array( $activity->id, $this->get_user_favorites(), true ),\n\t\t);\n\n\t\t// Get item schema.\n\t\t$schema = $this->get_item_schema();\n\n\t\t// Get comments (count).\n\t\tif ( ! empty( $activity->children ) ) {\n\t\t\t$comment_count         = wp_filter_object_list( $activity->children, array( 'type' => 'activity_comment' ), 'AND', 'id' );\n\t\t\t$data['comment_count'] = ! empty( $comment_count ) ? count( $comment_count ) : 0;\n\n\t\t\tif ( ! empty( $schema['properties']['comments'] ) && 'threaded' === $request->get_param( 'display_comments' ) ) {\n\t\t\t\t$data['comments'] = $this->prepare_activity_comments( $activity->children, $request );\n\t\t\t}\n\t\t}\n\n\t\tif ( true === buddypress()->avatar->show_avatars ) {\n\t\t\t$data['user_avatar'] = array(\n\t\t\t\t'full'  => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'item_id' => $activity->user_id,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t\t'type'    => 'full',\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t\t'thumb' => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'item_id' => $activity->user_id,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t$response->add_links( $this->prepare_links( $activity ) );\n\n\t\t/**\n\t\t * Filter an activity value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response     $response The response data.\n\t\t * @param WP_REST_Request      $request  Request used to generate the response.\n\t\t * @param BP_Activity_Activity $activity The activity object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_prepare_value', $response, $request, $activity );\n\t}\n\n\t/**\n\t * Prepare activity comments.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  array           $comments Array of comments.\n\t * @param  WP_REST_Request $request  Full details about the request.\n\t * @return array           An array of activity comments.\n\t */\n\tprotected function prepare_activity_comments( $comments, $request ) {\n\t\t$data = array();\n\n\t\tif ( empty( $comments ) ) {\n\t\t\treturn $data;\n\t\t}\n\n\t\tforeach ( $comments as $comment ) {\n\t\t\t$data[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $comment, $request )\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter activity comments returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $data     An array of activity comments with proper API response.\n\t\t * @param array           $comments An array of activity comments.\n\t\t * @param WP_REST_Request $request  Full details about the request.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_prepare_comments', $data, $comments, $request );\n\t}\n\n\t/**\n\t * Prepare an activity for create or update.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return stdClass|WP_Error Object or WP_Error.\n\t */\n\tprotected function prepare_item_for_database( $request ) {\n\t\t$prepared_activity = new stdClass();\n\t\t$schema            = $this->get_item_schema();\n\t\t$activity          = $this->get_activity_object( $request );\n\n\t\tif ( ! empty( $schema['properties']['id'] ) && ! empty( $activity->id ) ) {\n\t\t\t$prepared_activity->id = $activity->id;\n\n\t\t\tif ( 'activity_comment' !== $request->get_param( 'type' ) ) {\n\t\t\t\t$prepared_activity->error_type = 'wp_error';\n\t\t\t}\n\t\t}\n\n\t\t// Activity author ID.\n\t\tif ( ! empty( $activity->user_id ) ) {\n\t\t\t$prepared_activity->user_id = (int) $activity->user_id;\n\t\t} else {\n\t\t\t$prepared_activity->user_id = get_current_user_id();\n\t\t}\n\n\t\t// Activity component.\n\t\tif ( ! empty( $schema['properties']['component'] ) && ! empty( $request->get_param( 'component' ) ) ) {\n\t\t\t$prepared_activity->component = $request->get_param( 'component' );\n\t\t} else {\n\t\t\t$prepared_activity->component = buddypress()->activity->id;\n\t\t}\n\n\t\t// Activity date.\n\t\tif ( ! empty( $activity->date_recorded ) ) {\n\t\t\t$prepared_activity->recorded_time = $activity->date_recorded;\n\t\t}\n\n\t\t// Activity Item ID.\n\t\tif ( ! empty( $schema['properties']['primary_item_id'] ) && ! empty( $request->get_param( 'primary_item_id' ) ) ) {\n\t\t\t$item_id = (int) $request->get_param( 'primary_item_id' );\n\n\t\t\t// Use a generic item ID.\n\t\t\t$prepared_activity->item_id = $item_id;\n\n\t\t\t// Set the group ID, used in the `groups_post_update` helper function only.\n\t\t\tif ( bp_is_active( 'groups' ) && isset( $prepared_activity->component ) && buddypress()->groups->id === $prepared_activity->component ) {\n\t\t\t\t$prepared_activity->group_id = $item_id;\n\t\t\t}\n\t\t}\n\n\t\t// Secondary Item ID.\n\t\tif ( ! empty( $schema['properties']['secondary_item_id'] ) && ! empty( $request->get_param( 'secondary_item_id' ) ) ) {\n\t\t\t$prepared_activity->secondary_item_id = (int) $request->get_param( 'secondary_item_id' );\n\t\t}\n\n\t\t// Activity type.\n\t\tif ( ! empty( $schema['properties']['type'] ) && ! empty( $request->get_param( 'type' ) ) ) {\n\t\t\t$prepared_activity->type = $request->get_param( 'type' );\n\t\t}\n\n\t\t// Activity content.\n\t\tif ( ! empty( $schema['properties']['content'] ) && ! empty( $request->get_param( 'content' ) ) ) {\n\t\t\tif ( is_string( $request->get_param( 'content' ) ) ) {\n\t\t\t\t$prepared_activity->content = $request->get_param( 'content' );\n\t\t\t} elseif ( isset( $request['content']['raw'] ) ) {\n\t\t\t\t$prepared_activity->content = $request['content']['raw'];\n\t\t\t}\n\t\t}\n\n\t\t// Activity Sitewide visibility.\n\t\tif ( ! empty( $schema['properties']['hidden'] ) ) {\n\t\t\t$is_hidden = $request->get_param( 'hidden' );\n\n\t\t\tif ( ! is_null( $is_hidden ) ) {\n\t\t\t\t$is_hidden = wp_validate_boolean( $is_hidden );\n\t\t\t} elseif ( isset( $activity->hide_sitewide ) ) {\n\t\t\t\t$is_hidden = (bool) $activity->hide_sitewide;\n\t\t\t} elseif ( bp_is_active( 'groups' ) && isset( $prepared_activity->item_id, $prepared_activity->component ) && $prepared_activity->item_id && buddypress()->groups->id === $prepared_activity->component ) {\n\t\t\t\t$group     = bp_get_group_by( 'id', $prepared_activity->item_id );\n\t\t\t\t$is_hidden = isset( $group->status ) && 'public' !== $group->status;\n\t\t\t}\n\n\t\t\t$prepared_activity->hide_sitewide = $is_hidden;\n\t\t}\n\n\t\t/**\n\t\t * Filters an activity before it is inserted or updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param stdClass        $prepared_activity An object prepared for inserting or updating the database.\n\t\t * @param WP_REST_Request $request Request object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_pre_insert_value', $prepared_activity, $request );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Activity_Activity $activity Activity object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $activity ) {\n\t\t$base = sprintf( '/%1$s/%2$s/', $this->namespace, $this->rest_base );\n\t\t$url  = $base . $activity->id;\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $url ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\t// Embeds.\n\t\tif ( ! empty( $activity->user_id ) ) {\n\t\t\t$links['user'] = array(\n\t\t\t\t'href'       => bp_rest_get_object_url( absint( $activity->user_id ), 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t);\n\t\t}\n\n\t\tif ( 'activity_comment' === $activity->type ) {\n\t\t\t$links['up'] = array(\n\t\t\t\t'href' => rest_url( $url ),\n\t\t\t);\n\t\t}\n\n\t\t// Embed Group.\n\t\tif ( bp_is_active( 'groups' ) && buddypress()->groups->id === $activity->component && ! empty( $activity->item_id ) ) {\n\t\t\t$links['group'] = array(\n\t\t\t\t'embeddable' => true,\n\t\t\t\t'href'       => rest_url(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t'/%1$s/%2$s/%3$d',\n\t\t\t\t\t\t$this->namespace,\n\t\t\t\t\t\tbuddypress()->groups->id,\n\t\t\t\t\t\tabsint( $activity->item_id )\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Embed Blog.\n\t\tif ( is_multisite() && bp_is_active( 'blogs' ) && buddypress()->blogs->id === $activity->component && ! empty( $activity->item_id ) ) {\n\t\t\t$links['blog'] = array(\n\t\t\t\t'embeddable' => true,\n\t\t\t\t'href'       => rest_url(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t'/%1$s/%2$s/%3$d',\n\t\t\t\t\t\t$this->namespace,\n\t\t\t\t\t\tbuddypress()->blogs->id,\n\t\t\t\t\t\tabsint( $activity->item_id )\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Actions.\n\t\tif ( is_user_logged_in() && bp_activity_can_favorite() ) {\n\t\t\t$favorite_action = array(\n\t\t\t\t'href'        => rest_url( $url . '/favorite' ),\n\t\t\t\t'activity_id' => $activity->id,\n\t\t\t);\n\n\t\t\t// Will be deprecated.\n\t\t\t$links['favorite']           = $favorite_action;\n\t\t\t$links['bp-action-favorite'] = $favorite_action;\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array                $links     The prepared links of the REST response.\n\t\t * @param BP_Activity_Activity $activity  Activity object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_prepare_links', $links, $activity );\n\t}\n\n\t/**\n\t * Can this user see the activity?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return boolean\n\t */\n\tprotected function can_see( $request ) {\n\t\treturn bp_activity_user_can_read(\n\t\t\t$this->get_activity_object( $request ),\n\t\t\tbp_loggedin_user_id()\n\t\t);\n\t}\n\n\t/**\n\t * Show hidden activity?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  string $component The component the activity is from.\n\t * @param  int    $item_id   The activity item ID.\n\t * @return boolean\n\t */\n\tprotected function show_hidden( $component, $item_id ) {\n\t\t$user_id = get_current_user_id();\n\t\t$retval  = false;\n\n\t\tif ( ! is_null( $component ) ) {\n\t\t\t// If activity is from a group, check the user is a confirmed member/admin or mod of the group.\n\t\t\tif ( 'groups' === $component && bp_is_active( 'groups' ) && ! empty( $item_id ) ) {\n\t\t\t\t$retval = (bool) groups_is_user_member( $user_id, $item_id );\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Filter here to manage hidden activity for the component.\n\t\t\t *\n\t\t\t * @since 0.7.0\n\t\t\t *\n\t\t\t * @param bool   $retval    True to show hidden activities. False otherwise.\n\t\t\t * @param string $component The component name/ID.\n\t\t\t * @param int    $user_id   The current user ID.\n\t\t\t */\n\t\t\t$retval = apply_filters( 'bp_rest_activity_show_hidden', $retval, $component, $user_id );\n\t\t}\n\n\t\t// Moderators as well.\n\t\tif ( bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\treturn (bool) $retval;\n\t}\n\n\t/**\n\t * Get activity object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return BP_Activity_Activity|string An activity object.\n\t */\n\tpublic function get_activity_object( $request ) {\n\t\t$activity_id = is_numeric( $request ) ? $request : (int) $request->get_param( 'id' );\n\n\t\t$activity = bp_activity_get_specific(\n\t\t\tarray(\n\t\t\t\t'activity_ids'     => array( $activity_id ),\n\t\t\t\t'display_comments' => true,\n\t\t\t)\n\t\t);\n\n\t\tif ( is_array( $activity ) && ! empty( $activity['activities'][0] ) ) {\n\t\t\treturn $activity['activities'][0];\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Edit the type of the some properties for the CREATABLE & EDITABLE methods.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key                     = 'create_item';\n\t\t\t$args['content']['type'] = 'string';\n\t\t\tunset( $args['content']['properties'] );\n\n\t\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t\t$key                      = 'update_item';\n\t\t\t\t$args['type']['required'] = true;\n\t\t\t}\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_activity_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the plugin schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_activity',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the activity.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'primary_item_id'   => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The ID of some other object primarily associated with this one.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'secondary_item_id' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The ID of some other object also associated with this one.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'user_id'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The ID for the author of the activity.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'link'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The permalink to this activity on the site.', 'buddypress' ),\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'component'         => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The active BuddyPress component the activity relates to.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => array_keys( buddypress()->active_components ),\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'type'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The activity type of the activity.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => array_keys( bp_activity_get_types() ),\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'title'             => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The description of the activity\\'s type (eg: Username posted an update)', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'content'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Allowed HTML content for the activity.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t\t'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the activity, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the activity, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'date'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The date the activity was published, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_gmt'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the activity was published, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'status'            => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Whether the activity has been marked as spam or not.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => array( 'published', 'spam' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'comments'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'A list of objects children of the activity object.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'comment_count'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Total number of comments of the activity object.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'hidden'            => array(\n\t\t\t\t\t\t'context'     => array( 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Whether the activity object should be sitewide hidden or not.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t\t'favorited'         => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Whether the activity object has been favorited by the current user.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tif ( true === buddypress()->avatar->show_avatars ) {\n\t\t\t\t$avatar_properties = array();\n\n\t\t\t\t$avatar_properties['full'] = array(\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t/* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t);\n\n\t\t\t\t$avatar_properties['thumb'] = array(\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t/* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t);\n\n\t\t\t\t$schema['properties']['user_avatar'] = array(\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t'description' => __( 'Avatar URLs for the author of the activity.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t'properties'  => $avatar_properties,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Cache current schema here.\n\t\t\t$this->schema = $schema;\n\t\t}\n\n\t\t/**\n\t\t * Filters the activity schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections of plugins.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t$params['exclude'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes specific IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['include'] = array(\n\t\t\t'description'       => __( 'Ensure result set includes specific IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['order'] = array(\n\t\t\t'description'       => __( 'Order sort attribute ascending or descending.', 'buddypress' ),\n\t\t\t'default'           => 'desc',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'asc', 'desc' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['after'] = array(\n\t\t\t'description'       => __( 'Limit result set to items published after a given ISO8601 compliant date.', 'buddypress' ),\n\t\t\t'type'              => 'string',\n\t\t\t'format'            => 'date-time',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to items created by a specific user (ID).', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['status'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific status.', 'buddypress' ),\n\t\t\t'default'           => 'ham_only',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'ham_only', 'spam_only', 'all' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['scope'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific scope.', 'buddypress' ),\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'just-me', 'friends', 'groups', 'favorites', 'mentions' ),\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['group_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to items created by a specific group.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['site_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to items created by a specific site.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['primary_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific prime association ID.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['secondary_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific secondary association ID.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['component'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific active BuddyPress component.', 'buddypress' ),\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array_keys( buddypress()->active_components ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['type'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific activity type.', 'buddypress' ),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array(\n\t\t\t\t'enum' => array_keys( bp_activity_get_types() ),\n\t\t\t\t'type' => 'string',\n\t\t\t),\n\t\t\t'sanitize_callback' => 'wp_parse_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['display_comments'] = array(\n\t\t\t'description'       => __( 'No comments by default, stream for within stream display, threaded for below each activity item.', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_activity_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-attachments/classes/trait-attachments.php",
    "content": "<?php\n/**\n * BP REST: Attachments Trait\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Attachments Trait\n *\n * @since 0.1.0\n */\ntrait BP_REST_Attachments {\n\n\t/**\n\t * Cover upload from file.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param array $file $_FILES superglobal.\n\t * @return string|WP_Error\n\t */\n\tprotected function upload_cover_from_file( $file ) {\n\n\t\t// Set global variables.\n\t\t$bp = buddypress();\n\t\tswitch ( $this->object ) {\n\t\t\tcase 'group':\n\t\t\t\t$bp->groups->current_group = $this->group;\n\t\t\t\t$bp->current_component     = 'groups';\n\t\t\t\tbreak;\n\t\t\tcase 'user':\n\t\t\tdefault:\n\t\t\t\t$bp->displayed_user     = new stdClass();\n\t\t\t\t$bp->displayed_user->id = (int) $this->user->ID;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Try to upload image.\n\t\t$uploaded_image = $this->attachment_instance->upload( $file );\n\n\t\t// Bail with error.\n\t\tif ( ! empty( $uploaded_image['error'] ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_cover_upload_error\",\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %s: the upload error message */\n\t\t\t\t\t__( 'Upload Failed! Error was: %s', 'buddypress' ),\n\t\t\t\t\t$uploaded_image['error']\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t\t'reason' => 'upload_error',\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$component                  = $this->get_cover_object_component();\n\t\t$item_id                    = $this->get_item_id();\n\t\t$bp_attachments_uploads_dir = bp_attachments_cover_image_upload_dir(\n\t\t\tarray(\n\t\t\t\t'object_directory' => $component,\n\t\t\t\t'object_id'        => $item_id,\n\t\t\t)\n\t\t);\n\n\t\t// The BP Attachments Uploads Dir is not set, stop.\n\t\tif ( ! $bp_attachments_uploads_dir ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_cover_upload_error\",\n\t\t\t\t__( 'The BuddyPress attachments uploads directory is not set.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t\t'reason' => 'attachments_upload_dir',\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$cover_subdir = $bp_attachments_uploads_dir['subdir'];\n\t\t$cover_dir    = $bp_attachments_uploads_dir['basedir'] . $cover_subdir;\n\n\t\t// If upload path doesn't exist, stop.\n\t\tif ( 1 === validate_file( $cover_dir ) || ! is_dir( $cover_dir ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_cover_upload_error\",\n\t\t\t\t__( 'The cover image directory is not valid.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t\t'reason' => 'cover_image_dir',\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Upload cover.\n\t\t$cover = bp_attachments_cover_image_generate_file(\n\t\t\tarray(\n\t\t\t\t'file'            => $uploaded_image['file'],\n\t\t\t\t'component'       => $component,\n\t\t\t\t'cover_image_dir' => $cover_dir,\n\t\t\t)\n\t\t);\n\n\t\t// Bail if any error happened.\n\t\tif ( false === $cover ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_cover_upload_error\",\n\t\t\t\t__( 'There was a problem uploading the cover image.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t\t'reason' => 'unknown',\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Bail with error if too small.\n\t\tif ( true === $cover['is_too_small'] ) {\n\n\t\t\t// Get cover image advised dimensions.\n\t\t\t$cover_dimensions = bp_attachments_get_cover_image_dimensions( $component );\n\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_cover_upload_error\",\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %$1s and %$2s is replaced with the correct sizes. */\n\t\t\t\t\t__( 'You have selected an image that is smaller than recommended. For better results, make sure to upload an image that is larger than %1$spx wide, and %2$spx tall.', 'buddypress' ),\n\t\t\t\t\t(int) $cover_dimensions['width'],\n\t\t\t\t\t(int) $cover_dimensions['height']\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'status'     => 400,\n\t\t\t\t\t'reason'     => 'image_too_small',\n\t\t\t\t\t'min_width'  => (int) $cover_dimensions['width'],\n\t\t\t\t\t'min_height' => (int) $cover_dimensions['height'],\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\treturn sprintf(\n\t\t\t'%1$s/%2$s/%3$s',\n\t\t\t$bp_attachments_uploads_dir['baseurl'],\n\t\t\t$cover_subdir,\n\t\t\t$cover['cover_basename']\n\t\t);\n\t}\n\n\t/**\n\t * Avatar upload from File.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param array $files $_FILES superglobal.\n\t * @return stdClass|WP_Error\n\t */\n\tprotected function upload_avatar_from_file( $files ) {\n\n\t\t// Set global variables.\n\t\t$bp = buddypress();\n\t\tswitch ( $this->object ) {\n\t\t\tcase 'group':\n\t\t\t\t$bp->groups->current_group = $this->group;\n\t\t\t\t$upload_main_dir           = 'groups_avatar_upload_dir';\n\t\t\t\tbreak;\n\t\t\tcase 'user':\n\t\t\tdefault:\n\t\t\t\t$upload_main_dir        = 'bp_members_avatar_upload_dir';\n\t\t\t\t$bp->displayed_user     = new stdClass();\n\t\t\t\t$bp->displayed_user->id = (int) $this->user->ID;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t$avatar_attachment = $this->avatar_instance;\n\t\t$avatar_original   = $avatar_attachment->upload( $files, $upload_main_dir );\n\n\t\t// Bail early in case of an error.\n\t\tif ( ! empty( $avatar_original['error'] ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_avatar_upload_error\",\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %s: the upload error message */\n\t\t\t\t\t__( 'Upload failed! Error was: %s.', 'buddypress' ),\n\t\t\t\t\t$avatar_original['error']\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t\t'reason' => 'upload_error',\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get image and bail early if there is an error.\n\t\t$image_file = $this->resize( $avatar_original['file'] );\n\t\tif ( is_wp_error( $image_file ) ) {\n\t\t\treturn $image_file;\n\t\t}\n\n\t\t// If the uploaded image is smaller than the \"full\" dimensions, throw a warning.\n\t\tif ( $avatar_attachment->is_too_small( $image_file ) ) {\n\t\t\t$full_width  = bp_core_avatar_full_width();\n\t\t\t$full_height = bp_core_avatar_full_height();\n\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_avatar_error\",\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %1$s and %2$s is replaced with the correct sizes. */\n\t\t\t\t\t__( 'You have selected an image that is smaller than recommended. For best results, upload a picture larger than %1$s x %2$s pixels.', 'buddypress' ),\n\t\t\t\t\t$full_width,\n\t\t\t\t\t$full_height\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'status'     => 400,\n\t\t\t\t\t'reason'     => 'image_too_small',\n\t\t\t\t\t'min_width'  => $full_width,\n\t\t\t\t\t'min_height' => $full_height,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Delete existing image if one exists.\n\t\t$this->delete_existing_image();\n\n\t\t// Crop the profile photo accordingly and bail early in case of an error.\n\t\t$cropped = $this->crop_image( $image_file );\n\t\tif ( is_wp_error( $cropped ) ) {\n\t\t\treturn $cropped;\n\t\t}\n\n\t\t// Set the arguments for the avatar.\n\t\t$args = array();\n\t\tforeach ( array( 'full', 'thumb' ) as $key_type ) {\n\n\t\t\t// Update path with an url.\n\t\t\t$url = str_replace( bp_core_avatar_upload_path(), '', $cropped[ $key_type ] );\n\n\t\t\t// Set image url to its size/type.\n\t\t\t$args[ $key_type ] = bp_core_avatar_url() . $url;\n\t\t}\n\n\t\t// Build response object.\n\t\t$avatar_object = $this->get_avatar_object( $args );\n\n\t\tif ( file_exists( $avatar_original['file'] ) ) {\n\t\t\twp_delete_file( $avatar_original['file'] );\n\t\t}\n\n\t\treturn $avatar_object;\n\t}\n\n\t/**\n\t * Resize image.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $file Image to resize.\n\t * @return string|WP_Error\n\t */\n\tprotected function resize( $file ) {\n\t\t$bp          = buddypress();\n\t\t$upload_path = bp_core_avatar_upload_path();\n\n\t\tif ( ! isset( $bp->avatar_admin ) ) {\n\t\t\t$bp->avatar_admin = new stdClass();\n\t\t}\n\n\t\t// The Avatar UI available width.\n\t\t$ui_available_width = 0;\n\n\t\t// Try to set the ui_available_width using the avatar_admin global.\n\t\tif ( isset( $bp->avatar_admin->ui_available_width ) ) {\n\t\t\t$ui_available_width = $bp->avatar_admin->ui_available_width;\n\t\t}\n\n\t\t$resized = $this->avatar_instance->shrink( $file, $ui_available_width );\n\n\t\t// We only want to handle one image after resize.\n\t\tif ( empty( $resized ) ) {\n\t\t\t$image_file = $file;\n\t\t\t$img_dir    = str_replace( $upload_path, '', $file );\n\t\t} else {\n\t\t\t$image_file = $resized['path'];\n\t\t\t$img_dir    = str_replace( $upload_path, '', $resized['path'] );\n\n\t\t\twp_delete_file( $file );\n\t\t}\n\n\t\t// Check for WP_Error on what should be an image.\n\t\tif ( is_wp_error( $img_dir ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_avatar_upload_error\",\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %s: the upload error message */\n\t\t\t\t\t__( 'Upload failed! Error was: %s', 'buddypress' ),\n\t\t\t\t\t$img_dir->get_error_message()\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t\t'reason' => 'resize_error',\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\treturn $image_file;\n\t}\n\n\t/**\n\t * Crop image.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $image_file Image to crop.\n\t * @return array|WP_Error\n\t */\n\tprotected function crop_image( $image_file ) {\n\t\t$image          = getimagesize( $image_file );\n\t\t$avatar_to_crop = str_replace( bp_core_avatar_upload_path(), '', $image_file );\n\n\t\t// Get avatar full width and height.\n\t\t$full_height = bp_core_avatar_full_height();\n\t\t$full_width  = bp_core_avatar_full_width();\n\n\t\t// Use as much as possible of the image.\n\t\t$avatar_ratio = $full_width / $full_height;\n\t\t$image_ratio  = $image[0] / $image[1];\n\n\t\tif ( $image_ratio >= $avatar_ratio ) {\n\t\t\t// Uploaded image is wider than BP ratio, so we crop horizontally.\n\t\t\t$crop_y = 0;\n\t\t\t$crop_h = $image[1];\n\n\t\t\t// Get the target width by multiplying unmodified image height by target ratio.\n\t\t\t$crop_w    = $avatar_ratio * $image[1];\n\t\t\t$padding_w = round( ( $image[0] - $crop_w ) / 2 );\n\t\t\t$crop_x    = $padding_w;\n\t\t} else {\n\t\t\t// Uploaded image is narrower than BP ratio, so we crop vertically.\n\t\t\t$crop_x = 0;\n\t\t\t$crop_w = $image[0];\n\n\t\t\t// Get the target height by multiplying unmodified image width by target ratio.\n\t\t\t$crop_h    = $avatar_ratio * $image[0];\n\t\t\t$padding_h = round( ( $image[1] - $crop_h ) / 2 );\n\t\t\t$crop_y    = $padding_h;\n\t\t}\n\n\t\tadd_filter( 'bp_attachments_current_user_can', '__return_true' );\n\n\t\t// Crop the image.\n\t\t$cropped = $this->avatar_instance->crop(\n\t\t\tarray(\n\t\t\t\t'object'        => $this->object,\n\t\t\t\t'avatar_dir'    => ( 'group' === $this->object ) ? 'group-avatars' : 'avatars',\n\t\t\t\t'item_id'       => $this->get_item_id(),\n\t\t\t\t'original_file' => $avatar_to_crop,\n\t\t\t\t'crop_w'        => $crop_w,\n\t\t\t\t'crop_h'        => $crop_h,\n\t\t\t\t'crop_x'        => $crop_x,\n\t\t\t\t'crop_y'        => $crop_y,\n\t\t\t)\n\t\t);\n\n\t\tremove_filter( 'bp_attachments_current_user_can', '__return_false' );\n\n\t\t// Check for errors.\n\t\tif ( empty( $cropped['full'] ) || empty( $cropped['thumb'] ) || is_wp_error( $cropped['full'] ) || is_wp_error( $cropped['thumb'] ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t\"bp_rest_attachments_{$this->object}_avatar_crop_error\",\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %s is replaced with object type. */\n\t\t\t\t\t__( 'There was a problem cropping your %s photo.', 'buddypress' ),\n\t\t\t\t\t$this->object\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\treturn $cropped;\n\t}\n\n\t/**\n\t * Delete group's existing avatar if one exists.\n\t *\n\t * @since 0.1.0\n\t */\n\tprotected function delete_existing_image() {\n\t\t// Get existing avatar.\n\t\t$existing_avatar = bp_core_fetch_avatar(\n\t\t\tarray(\n\t\t\t\t'object'  => $this->object,\n\t\t\t\t'item_id' => $this->get_item_id(),\n\t\t\t\t'html'    => false,\n\t\t\t)\n\t\t);\n\n\t\t// Check if the avatar exists before deleting.\n\t\tif ( ! empty( $existing_avatar ) ) {\n\t\t\tbp_core_delete_existing_avatar(\n\t\t\t\tarray(\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t\t'item_id' => $this->get_item_id(),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Returns the avatar object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param array $args {\n\t *    An array of arguments to build the Avatar object.\n\t *\n\t *    @type string $full  The url to the full version of the avatar.\n\t *    @type string $thumb The url to the thumb version of the avatar.\n\t * }\n\t * @return object The avatar object.\n\t */\n\tprotected function get_avatar_object( $args = array() ) {\n\t\t$avatar_object = array_intersect_key(\n\t\t\t$args,\n\t\t\tarray(\n\t\t\t\t'full'  => '',\n\t\t\t\t'thumb' => '',\n\t\t\t)\n\t\t);\n\n\t\treturn (object) $avatar_object;\n\t}\n\n\t/**\n\t * Get item id.\n\t *\n\t * @since 5.0.0\n\t *\n\t * @return int\n\t */\n\tprotected function get_item_id() {\n\t\treturn ( 'group' === $this->object ) ? $this->group->id : $this->user->ID;\n\t}\n\n\t/**\n\t * Get cover object component.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return string\n\t */\n\tprotected function get_cover_object_component() {\n\t\treturn ( 'group' === $this->object ) ? 'groups' : 'members';\n\t}\n}\n"
  },
  {
    "path": "includes/bp-blogs/classes/class-bp-rest-attachments-blog-avatar-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Attachments_Blog_Avatar_Endpoint class\n *\n * @package BuddyPress\n * @since 6.0.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Blog avatar endpoints.\n *\n * @since 6.0.0\n */\nclass BP_REST_Attachments_Blog_Avatar_Endpoint extends WP_REST_Controller {\n\tuse BP_REST_Attachments;\n\n\t/**\n\t * Reuse some parts of the BP_REST_Blogs_Endpoint class.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var BP_REST_Blogs_Endpoint\n\t */\n\tprotected $blogs_endpoint;\n\n\t/**\n\t * This variable is used to query for the requested blog only once.\n\t * It is set during the permission check methods.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var BP_Blogs_Blog\n\t */\n\tprotected $blog;\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Blogs_Avatar_REST_Controller' );\n\n\t\t$this->namespace      = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base      = buddypress()->blogs->id;\n\t\t$this->blogs_endpoint = new BP_REST_Blogs_Endpoint();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)/avatar',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the blog.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_item_collection_params(),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Fetch an existing blog avatar.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$no_user_grav = (bool) $request->get_param( 'no_user_gravatar' );\n\n\t\tif ( empty( $this->blog->admin_user_id ) && ! $no_user_grav ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_blog_avatar_get_item_user_failed',\n\t\t\t\t__( 'There was a problem confirming the blog\\'s user admin is valid.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Set the requested args.\n\t\t$requested_args = array(\n\t\t\t'blog_id' => $request->get_param( 'id' ),\n\t\t\t'no_grav' => $no_user_grav,\n\t\t\t'html'    => (bool) $request->get_param( 'html' ),\n\t\t);\n\n\t\tif ( ! empty( $request->get_param( 'alt' ) ) ) {\n\t\t\t$requested_args['alt'] = $request->get_param( 'alt' );\n\t\t}\n\n\t\tif ( ! $no_user_grav ) {\n\t\t\t$requested_args['admin_user_id'] = (int) $this->blog->admin_user_id;\n\n\t\t\tif ( ! isset( $requested_args['alt'] ) ) {\n\t\t\t\t$requested_args['alt'] = '';\n\t\t\t}\n\t\t}\n\n\t\t$args = array();\n\t\tforeach ( array( 'full', 'thumb' ) as $type ) {\n\t\t\t$requested_args['type'] = $type;\n\t\t\t$args[ $type ]          = bp_get_blog_avatar( $requested_args );\n\t\t}\n\n\t\t// Get the avatar object.\n\t\t$avatar = $this->get_avatar_object( $args );\n\n\t\tif ( ! $avatar->full && ! $avatar->thumb ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_blog_avatar_no_image',\n\t\t\t\t__( 'Sorry, there was a problem fetching the blog avatar.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $avatar, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a blog avatar is fetched via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param stdClass          $avatar   The avatar object.\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_blog_avatar_get_item', $avatar, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to get a blog avatar.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'blogs' ) ) ) {\n\t\t\t$this->blog = $this->blogs_endpoint->get_blog_object( $request->get_param( 'id' ) );\n\n\t\t\tif ( ! is_object( $this->blog ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_blog_invalid_id',\n\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t);\n\t\t\t} elseif ( buddypress()->avatar->show_avatars ) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_attachments_blog_avatar_disabled',\n\t\t\t\t\t__( 'Sorry, blog avatar is disabled.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 500 )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the blog avatar `get_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_blog_avatar_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares avatar data to return as an object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param stdClass        $avatar  Avatar object.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $avatar, $request ) {\n\t\t$data = array(\n\t\t\t'full'  => $avatar->full,\n\t\t\t'thumb' => $avatar->thumb,\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t/**\n\t\t * Filter a blog avatar value returned from the API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param WP_REST_Response  $response Response.\n\t\t * @param WP_REST_Request   $request  Request used to generate the response.\n\t\t * @param object            $avatar   Avatar object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_blog_avatar_prepare_value', $response, $request, $avatar );\n\t}\n\n\t/**\n\t * Get the blog avatar schema, conforming to JSON Schema.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_attachments_blog_avatar',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'full'  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Full size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'thumb' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Thumb size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the blog avatar schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_blog_avatar_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for the `get_item`.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t// Removing unused params.\n\t\tunset( $params['search'], $params['page'], $params['per_page'] );\n\n\t\t$params['html'] = array(\n\t\t\t'description'       => __( 'Whether to return an <img> HTML element, vs a raw URL to an avatar.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['alt'] = array(\n\t\t\t'description'       => __( 'The alt attribute for the <img> element.', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['no_user_gravatar'] = array(\n\t\t\t'description'       => __( 'Whether to disable the default Gravatar Admin user fallback.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the item collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_blog_avatar_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-blogs/classes/class-bp-rest-blogs-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Blogs_Endpoint class\n *\n * @package BuddyPress\n * @since 6.0.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Blogs endpoints.\n *\n * Use /blogs/\n * Use /blogs/{id}\n *\n * @since 6.0.0\n */\nclass BP_REST_Blogs_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Blogs_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = buddypress()->blogs->id;\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Blog.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param(\n\t\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t\t'default' => 'view',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve Blogs.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'type'             => $request->get_param( 'type' ),\n\t\t\t'include_blog_ids' => $request->get_param( 'include' ),\n\t\t\t'user_id'          => $request->get_param( 'user_id' ),\n\t\t\t'search_terms'     => $request->get_param( 'search' ),\n\t\t\t'page'             => $request->get_param( 'page' ),\n\t\t\t'per_page'         => $request->get_param( 'per_page' ),\n\t\t);\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_blogs_get_items_query_args', $args, $request );\n\n\t\t// false is the default value for some args.\n\t\tforeach ( $args as $key => $value ) {\n\t\t\tif ( empty( $value ) ) {\n\t\t\t\t$args[ $key ] = false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if user is valid.\n\t\tif ( 0 !== absint( $args['user_id'] ) ) {\n\t\t\t$user = get_user_by( 'id', absint( $args['user_id'] ) );\n\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_blogs_get_items_user_failed',\n\t\t\t\t\t__( 'There was a problem confirming if user ID provided is a valid one.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Actually, query it.\n\t\t$blogs  = bp_blogs_get_blogs( $args );\n\t\t$retval = array();\n\t\tforeach ( (array) $blogs['blogs'] as $blog ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $blog, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $blogs['total'], $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after blogs are fetched via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array            $blogs     Fetched blogs.\n\t\t * @param WP_REST_Response $response  The response data.\n\t\t * @param WP_REST_Request  $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_blogs_get_items', $blogs, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to blog items.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'blogs' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the blogs `get_items` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_blogs_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve a blog.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$blog = $this->get_blog_object( $request->get_param( 'id' ) );\n\n\t\tif ( empty( $blog->blog_id ) || empty( $blog->admin_user_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_blog_invalid_id',\n\t\t\t\t__( 'Invalid blog ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $blog, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a blog is fetched via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param stdClass         $blog     Fetched blog.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_blogs_get_item', $blog, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get information about a specific blog.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'blogs' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the blog `get_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_blogs_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Create a new blog.\n\t *\n\t * @since 7.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get WP_User object.\n\t\t$user = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\n\t\t// Validate blog signup.\n\t\t$blog_meta = wpmu_validate_blog_signup(\n\t\t\t$request->get_param( 'name' ),\n\t\t\t$request->get_param( 'title' ),\n\t\t\t$user\n\t\t);\n\n\t\t// Check if validation failed.\n\t\tif ( is_wp_error( $blog_meta['errors'] ) && ! empty( $blog_meta['errors']->errors ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_blog_validation_failed',\n\t\t\t\t$blog_meta['errors']->get_error_message(),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$site_id = $request->get_param( 'site_id' );\n\t\t$meta    = $request->get_param( 'meta' );\n\n\t\t// Assign blog meta.\n\t\tif ( empty( $meta['public'] ) ) {\n\t\t\t$meta['public'] = 1;\n\t\t}\n\n\t\tif ( empty( $meta['lang_id'] ) ) {\n\t\t\t$meta['lang_id'] = 1;\n\t\t}\n\n\t\t/**\n\t\t * Filter the meta arguments for the new Blog.\n\t\t *\n\t\t * @since 7.0.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$meta = apply_filters( 'bp_rest_blogs_create_item_meta', $meta, $request );\n\n\t\t// Create blog.\n\t\t$blog_id = wpmu_create_blog(\n\t\t\t$blog_meta['domain'],\n\t\t\t$blog_meta['path'],\n\t\t\t$blog_meta['blog_title'],\n\t\t\t$user->ID,\n\t\t\t$meta,\n\t\t\t$site_id\n\t\t);\n\n\t\t// If something went wrong, bail it.\n\t\tif ( is_wp_error( $blog_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_blogs_create_error',\n\t\t\t\t__( 'There was a problem creating blog.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$blog = $this->get_blog_object( $blog_id );\n\n\t\tif ( empty( $blog->blog_id ) || empty( $blog->admin_user_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_blog_invalid_id',\n\t\t\t\t__( 'Invalid blog ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $blog, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a blog is created via the REST API.\n\t\t *\n\t\t * @since 7.0.0\n\t\t *\n\t\t * @param stdClass         $blog     Created blog.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_blogs_create_item', $blog, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to create a blog.\n\t *\n\t * @since 7.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\tif ( true === bp_blog_signup_enabled() ) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_blogs_signup_disabled',\n\t\t\t\t\t__( 'Sorry, blog creation is disabled.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 500,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the blogs `create_item` permissions check.\n\t\t *\n\t\t * @since 7.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_blogs_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares blogs data for return as an object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param stdClass        $blog    Blog object.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $blog, $request ) {\n\t\t$data = array(\n\t\t\t'id'                => absint( $blog->blog_id ),\n\t\t\t'user_id'           => absint( $blog->admin_user_id ),\n\t\t\t'name'              => apply_filters( 'bp_get_blog_name', $blog->name ),\n\t\t\t'domain'            => (string) $blog->domain,\n\t\t\t'path'              => (string) $blog->path,\n\t\t\t'permalink'         => $this->get_blog_permalink( $blog ),\n\t\t\t'last_activity'     => bp_rest_prepare_date_response( $blog->last_activity, get_date_from_gmt( $blog->last_activity ) ),\n\t\t\t'last_activity_gmt' => bp_rest_prepare_date_response( $blog->last_activity ),\n\t\t\t'lastest_post_id'   => 0,\n\t\t\t'description'       => array(\n\t\t\t\t'raw'      => $blog->description,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_blog_description', $blog->description ),\n\t\t\t),\n\t\t);\n\n\t\tif ( ! empty( $blog->latest_post->ID ) ) {\n\t\t\t$data['lastest_post_id'] = absint( $blog->latest_post->ID );\n\t\t}\n\n\t\t// Blog Avatars.\n\t\tif ( true === buddypress()->avatar->show_avatars ) {\n\t\t\t$data['avatar_urls'] = array(\n\t\t\t\t'thumb' => bp_get_blog_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'type'    => 'thumb',\n\t\t\t\t\t\t'blog_id' => $blog->blog_id,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t\t'full'  => bp_get_blog_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'type'    => 'full',\n\t\t\t\t\t\t'blog_id' => $blog->blog_id,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t$response->add_links( $this->prepare_links( $blog ) );\n\n\t\t/**\n\t\t * Filter a blog returned from the API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param WP_REST_Response  $response Response generated by the request.\n\t\t * @param WP_REST_Request   $request  Request used to generate the response.\n\t\t * @param stdClass          $blog     The blog object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_blogs_prepare_value', $response, $request, $blog );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param stdClass $blog Blog object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $blog ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $blog->blog_id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\tif ( ! empty( $blog->admin_user_id ) ) {\n\t\t\t$links['user'] = array(\n\t\t\t\t'href'       => bp_rest_get_object_url( absint( $blog->admin_user_id ), 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t);\n\t\t}\n\n\t\t// Embed the latest blog post.\n\t\tif ( ! empty( $blog->latest_post->ID ) ) {\n\t\t\t$links['post'] = array(\n\t\t\t\t'embeddable' => true,\n\t\t\t\t'href'       => sprintf(\n\t\t\t\t\t'%s/%d',\n\t\t\t\t\tget_rest_url( absint( $blog->blog_id ), 'wp/v2/posts' ),\n\t\t\t\t\tabsint( $blog->latest_post->ID )\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array    $links The prepared links of the REST response.\n\t\t * @param stdClass $blog  The blog object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_blogs_prepare_links', $links, $blog );\n\t}\n\n\t/**\n\t * Get blog permalink.\n\t *\n\t * @param stdClass $blog Blog object.\n\t * @return string\n\t */\n\tprotected function get_blog_permalink( $blog ) {\n\n\t\t// Bail early.\n\t\tif ( empty( $blog->domain ) && empty( $blog->path ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\tif ( empty( $blog->domain ) && ! empty( $blog->path ) ) {\n\t\t\treturn bp_get_root_url() . $blog->path;\n\t\t}\n\n\t\t$protocol  = is_ssl() ? 'https://' : 'http://';\n\t\t$permalink = $protocol . $blog->domain . $blog->path;\n\n\t\treturn apply_filters( 'bp_get_blog_permalink', $permalink );\n\t}\n\n\t/**\n\t * Get a blog object from a blog_id.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param int $blog_id Blog ID.\n\t * @return stdClass|int\n\t */\n\tpublic function get_blog_object( $blog_id ) {\n\t\t$blogs = current(\n\t\t\tbp_blogs_get_blogs(\n\t\t\t\tarray(\n\t\t\t\t\t'include_blog_ids' => array( $blog_id ),\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\t\tif ( ! empty( $blogs[0] ) ) {\n\t\t\treturn $blogs[0];\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Edit the type of the some properties for the CREATABLE method.\n\t *\n\t * @since 7.0.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\n\t\t\tunset( $args['last_activity'] );\n\n\t\t\t$args['name'] = array(\n\t\t\t\t'required'          => true,\n\t\t\t\t'description'       => __( 'The new site\\'s name (used for the site URL).', 'buddypress' ),\n\t\t\t\t'type'              => 'string',\n\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t\t$args['title'] = array(\n\t\t\t\t'required'          => true,\n\t\t\t\t'description'       => __( 'The new site\\'s title.', 'buddypress' ),\n\t\t\t\t'type'              => 'string',\n\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t\t$args['site_id'] = array(\n\t\t\t\t'required'          => false,\n\t\t\t\t'default'           => get_current_network_id(),\n\t\t\t\t'description'       => __( 'The new site\\'s network ID. (Only relevant on multi-network installations)', 'buddypress' ),\n\t\t\t\t'type'              => 'integer',\n\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t\t$args['user_id'] = array(\n\t\t\t\t'required'          => false,\n\t\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t\t'description'       => __( 'The user ID of the new site\\'s admin.', 'buddypress' ),\n\t\t\t\t'type'              => 'integer',\n\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t\t$args['meta'] = array(\n\t\t\t\t'required'          => false,\n\t\t\t\t'description'       => __( 'Set initial Blog options.', 'buddypress' ),\n\t\t\t\t'default'           => array(),\n\t\t\t\t'type'              => 'array',\n\t\t\t\t'items'             => array( 'type' => 'string' ),\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 7.0.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_blogs_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the blogs schema, conforming to JSON Schema.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_blogs',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the blog.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'user_id'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the blog admin.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'name'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The name of the blog.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'permalink'         => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The permalink of the blog.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t),\n\t\t\t\t\t'description'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The description of the blog.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the description of the blog, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the description of the blog, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'path'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The path of the blog.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'domain'            => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The domain of the blog.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'last_activity'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The date of the last activity from the blog, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'last_activity_gmt' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date of the last activity from the blog, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'lastest_post_id'   => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The latest post ID from the blog', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tif ( true === buddypress()->avatar->show_avatars ) {\n\t\t\t\t$avatar_properties = array();\n\n\t\t\t\t$avatar_properties['full'] = array(\n\t\t\t\t\t/* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t);\n\n\t\t\t\t$avatar_properties['thumb'] = array(\n\t\t\t\t\t/* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t);\n\n\t\t\t\t$schema['properties']['avatar_urls'] = array(\n\t\t\t\t\t'description' => __( 'Avatar URLs for the blog.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t'properties'  => $avatar_properties,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Cache current schema here.\n\t\t\t$this->schema = $schema;\n\t\t}\n\n\t\t/**\n\t\t * Filter the blogs schema.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_blogs_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for blogs collections.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'ID of the user whose blogs user can post to.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['include'] = array(\n\t\t\t'description'       => __( 'Ensure result set includes specific IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['type'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific type.', 'buddypress' ),\n\t\t\t'default'           => 'active',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'active', 'alphabetical', 'newest', 'random' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_blogs_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-components/classes/class-bp-rest-components-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Components_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Components endpoints.\n *\n * @since 0.1.0\n */\nclass BP_REST_Components_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Core_Components_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = 'components';\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'name'   => array(\n\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t\t'description' => __( 'Name of the component.', 'buddypress' ),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'action' => array(\n\t\t\t\t\t\t\t'description' => __( 'Whether to activate or deactivate the component.', 'buddypress' ),\n\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t'enum'        => array( 'activate', 'deactivate' ),\n\t\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve components.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'type'     => $request->get_param( 'type' ),\n\t\t\t'status'   => $request->get_param( 'status' ),\n\t\t\t'per_page' => $request->get_param( 'per_page' ),\n\t\t);\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_components_get_items_query_args', $args, $request );\n\n\t\t$type = $args['type'];\n\n\t\t// Get all components based on type.\n\t\t$components = bp_core_get_components( $type );\n\n\t\t// Active components.\n\t\t$active_components = (array) apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components' ) );\n\n\t\t// Core component is always active.\n\t\tif ( 'optional' !== $type && ! empty( $components['core'] ) ) {\n\t\t\t$active_components['core'] = '1';\n\t\t}\n\n\t\t// Inactive components.\n\t\t$inactive_components = array_diff( array_keys( $components ), array_keys( $active_components ) );\n\n\t\t$current_components = array();\n\t\tswitch ( $args['status'] ) {\n\t\t\tcase 'all':\n\t\t\t\tforeach ( array_keys( $components ) as $name ) {\n\t\t\t\t\t$current_components[] = $this->get_component_info( $name );\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'active':\n\t\t\t\tforeach ( array_keys( $active_components ) as $component ) {\n\t\t\t\t\t$current_components[] = $this->get_component_info( $component );\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'inactive':\n\t\t\t\tforeach ( $inactive_components as $component ) {\n\t\t\t\t\t$current_components[] = $this->get_component_info( $component );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t$retval = array();\n\t\tforeach ( $current_components as $component ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $component, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, count( $current_components ), $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a list of components is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $current_components Fetched components.\n\t\t * @param WP_REST_Response $response           The response data.\n\t\t * @param WP_REST_Request  $request            The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_components_get_items', $current_components, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to list components.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\t// The `get_items` endpoint can be used by BP Blocks to check whether some component's features are active or not.\n\t\tif ( bp_current_user_can( 'manage_options' ) || ( 'active' === $request->get_param( 'status' ) && current_user_can( 'publish_posts' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the components `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_components_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Activate/Deactivate a component.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t$component = $request->get_param( 'name' );\n\n\t\tif ( ! $this->component_exists( $component ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_component_nonexistent',\n\t\t\t\t__( 'Sorry, this component does not exist.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( 'activate' === $request->get_param( 'action' ) ) {\n\t\t\tif ( bp_is_active( $component ) ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_component_already_active',\n\t\t\t\t\t__( 'Sorry, this component is already active.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 400,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t$component_info = $this->activate_helper( $component );\n\t\t} else {\n\t\t\tif ( ! bp_is_active( $component ) ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_component_inactive',\n\t\t\t\t\t__( 'Sorry, this component is not active.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 400,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( array_key_exists( $component, bp_core_get_components( 'required' ) ) ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_required_component',\n\t\t\t\t\t__( 'Sorry, you cannot deactivate a required component.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 400,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t$component_info = $this->deactivate_helper( $component );\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $component_info, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a component is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array             $component_info Component info.\n\t\t * @param WP_REST_Response  $response       The response data.\n\t\t * @param WP_REST_Request   $request        The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_components_update_item', $component_info, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a component.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = $this->get_items_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the components `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_components_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares component data for return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param array           $component The component and its values.\n\t * @param WP_REST_Request $request   Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $component, $request ) {\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $component, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t/**\n\t\t * Filter a component value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response $response  The Response data.\n\t\t * @param WP_REST_Request  $request   Request used to generate the response.\n\t\t * @param array            $component The component and its values.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_components_prepare_value', $response, $request, $component );\n\t}\n\n\t/**\n\t * Verify Component Status.\n\t *\n\t * @since 0.1.0\n\t * @since 9.0.0 Adds the `$return_type` parameter.\n\t *\n\t * @param string $name        Component name.\n\t * @param string $return_type Use `string` to get the l10n string. Default.\n\t *                            Use `bool` to get whether the component is active or not.\n\t *                            Use `array` to get both information.\n\t * @return string|bool|array By default a l10n string is returned.\n\t *                           True if the component is active, false otherwise when 'bool' is requested.\n\t *                           An array containing both information when 'array' is requested.\n\t */\n\tprotected function verify_component_status( $name, $return_type = 'string' ) {\n\t\t$retval = array(\n\t\t\t'string' => __( 'inactive', 'buddypress' ),\n\t\t\t'bool'   => false,\n\t\t);\n\n\t\tif ( 'core' === $name || bp_is_active( $name ) ) {\n\t\t\t$retval = array(\n\t\t\t\t'string' => __( 'active', 'buddypress' ),\n\t\t\t\t'bool'   => true,\n\t\t\t);\n\t\t}\n\n\t\tif ( isset( $retval[ $return_type ] ) ) {\n\t\t\treturn $retval[ $return_type ];\n\t\t}\n\n\t\treturn $retval;\n\t}\n\n\t/**\n\t * Deactivate component helper.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $component Component id.\n\t * @return array\n\t */\n\tprotected function deactivate_helper( $component ) {\n\n\t\t$active_components =& buddypress()->active_components;\n\n\t\t// Set for the rest of the page load.\n\t\tunset( $active_components[ $component ] );\n\n\t\t// Save in the db.\n\t\tbp_update_option( 'bp-active-components', $active_components );\n\n\t\treturn $this->get_component_info( $component );\n\t}\n\n\t/**\n\t * Activate component helper.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $component Component id.\n\t * @return array\n\t */\n\tprotected function activate_helper( $component ) {\n\n\t\t$active_components =& buddypress()->active_components;\n\n\t\t// Set for the rest of the page load.\n\t\t$active_components[ $component ] = 1;\n\n\t\t// Save in the db.\n\t\tbp_update_option( 'bp-active-components', $active_components );\n\n\t\t// Ensure that dbDelta() is defined.\n\t\tif ( ! function_exists( 'dbDelta' ) ) {\n\t\t\trequire_once ABSPATH . 'wp-admin/includes/upgrade.php';\n\t\t}\n\n\t\t// Run the setup, in case tables have to be created.\n\t\trequire_once buddypress()->plugin_dir . 'bp-core/admin/bp-core-admin-schema.php';\n\n\t\tbp_core_install( $active_components );\n\t\tbp_core_add_page_mappings( $active_components );\n\n\t\treturn $this->get_component_info( $component );\n\t}\n\n\t/**\n\t * Get component info helper.\n\t *\n\t * @since 0.1.0\n\t * @since 9.0.0 Adds a `features` property to component's info.\n\t *\n\t * @param string $component Component id.\n\t * @return array\n\t */\n\tpublic function get_component_info( $component ) {\n\n\t\t// Get all components.\n\t\t$components = bp_core_get_components();\n\n\t\t// Init the component's data.\n\t\t$data = array();\n\n\t\t// Get specific component info.\n\t\tif ( isset( $components[ $component ] ) ) {\n\t\t\t$data = (array) $components[ $component ];\n\t\t}\n\n\t\t// Return empty early.\n\t\tif ( ! $data ) {\n\t\t\treturn $data;\n\t\t}\n\n\t\t// Get BuddyPress main instance.\n\t\t$bp = buddypress();\n\n\t\t// Get status data.\n\t\t$status = $this->verify_component_status( $component, 'array' );\n\n\t\t// Set component's basic information.\n\t\t$info = array(\n\t\t\t'name'        => $component,\n\t\t\t'status'      => $status['string'],\n\t\t\t'is_active'   => $status['bool'],\n\t\t\t'title'       => $data['title'],\n\t\t\t'description' => $data['description'],\n\t\t\t'features'    => array(),\n\t\t);\n\n\t\t// Set component's features.\n\t\tif ( $status['bool'] ) {\n\t\t\t// @todo check the features list is exhaustive.\n\t\t\tswitch ( $component ) {\n\t\t\t\tcase 'groups':\n\t\t\t\t\t$features = array(\n\t\t\t\t\t\t'avatar'         => $bp->avatar && $bp->avatar->show_avatars && ! bp_disable_group_avatar_uploads(),\n\t\t\t\t\t\t'cover'          => bp_is_active( 'groups', 'cover_image' ),\n\t\t\t\t\t\t'group_creation' => bp_restrict_group_creation() ? 'adminsonly' : 'members',\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'members':\n\t\t\t\t\t$features = array(\n\t\t\t\t\t\t'account_deletion'    => ! bp_disable_account_deletion(),\n\t\t\t\t\t\t'avatar'              => $bp->avatar && $bp->avatar->show_avatars,\n\t\t\t\t\t\t'cover'               => bp_is_active( 'members', 'cover_image' ),\n\t\t\t\t\t\t'invitations'         => bp_get_members_invitations_allowed(),\n\t\t\t\t\t\t'membership_requests' => bp_is_active( 'members', 'membership_requests' ) && ! bp_get_signup_allowed() && (bool) bp_get_option( 'bp-enable-membership-requests' ),\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'activity':\n\t\t\t\t\t$features = array(\n\t\t\t\t\t\t'auto_refresh' => bp_is_activity_heartbeat_active(),\n\t\t\t\t\t\t'embeds'       => bp_is_active( 'activity', 'embeds' ),\n\t\t\t\t\t\t'favorite'     => bp_activity_can_favorite(),\n\t\t\t\t\t\t'mentions'     => bp_activity_do_mentions(),\n\t\t\t\t\t\t'types'        => bp_activity_get_types_list(),\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'blogs':\n\t\t\t\t\t$features = array(\n\t\t\t\t\t\t'site_icon'       => bp_is_active( 'blogs', 'site-icon' ),\n\t\t\t\t\t\t'sites_directory' => is_multisite(),\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'messages':\n\t\t\t\t\t$features = array(\n\t\t\t\t\t\t'star' => bp_is_active( 'messages', 'star' ),\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t$features = array();\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Filter here to edit component's features.\n\t\t\t *\n\t\t\t * The dynamic portion of the filter is filled with the component's ID.\n\t\t\t *\n\t\t\t * @since 9.0.0\n\t\t\t *\n\t\t\t * @param array $features The component's features.\n\t\t\t */\n\t\t\t$info['features'] = apply_filters( 'bp_rest_' . $component . '_component_features', $features );\n\t\t}\n\n\t\treturn $info;\n\t}\n\n\t/**\n\t * Does the component exist?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $component Component.\n\t * @return bool\n\t */\n\tprotected function component_exists( $component ) {\n\t\treturn in_array( $component, array_keys( bp_core_get_components() ), true );\n\t}\n\n\t/**\n\t * Get the components schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_components',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'name'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Name of the object.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'is_active'   => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the component is active or not.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t\t'default'     => false,\n\t\t\t\t\t),\n\t\t\t\t\t'status'      => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the object is active or inactive.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t// We need to use what returns `$this->verify_component_status()` by default here.\n\t\t\t\t\t\t'enum'        => array(\n\t\t\t\t\t\t\t__( 'active', 'buddypress' ),\n\t\t\t\t\t\t\t__( 'inactive', 'buddypress' ),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'title'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'HTML title of the object.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'description' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'HTML description of the object.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'features'    => array(\n\t\t\t\t\t\t'description' => __( 'Information about active features for the component.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'default'     => array(),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the components schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_components_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t$params['status'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific status.', 'buddypress' ),\n\t\t\t'default'           => 'all',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'all', 'active', 'inactive' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['type'] = array(\n\t\t\t'description'       => __( 'Limit result set to items with a specific type.', 'buddypress' ),\n\t\t\t'default'           => 'all',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'all', 'optional', 'retired', 'required' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_components_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-friends/classes/class-bp-rest-friends-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Friends_Endpoint class\n *\n * @package BuddyPress\n * @since 6.0.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Friendship endpoints.\n *\n * /friends/\n * /friends/{id}\n *\n * @since 6.0.0\n */\nclass BP_REST_Friends_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Friends_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = buddypress()->friends->id;\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\w-]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'Numeric identifier of a user ID.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::DELETABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve friendships.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'id'                => $request->get_param( 'id' ),\n\t\t\t'initiator_user_id' => $request->get_param( 'initiator_id' ),\n\t\t\t'friend_user_id'    => $request->get_param( 'friend_id' ),\n\t\t\t'is_confirmed'      => $request->get_param( 'is_confirmed' ),\n\t\t\t'order_by'          => $request->get_param( 'order_by' ),\n\t\t\t'sort_order'        => strtoupper( $request->get_param( 'order' ) ),\n\t\t\t'page'              => $request->get_param( 'page' ),\n\t\t\t'per_page'          => $request->get_param( 'per_page' ),\n\t\t);\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_friends_get_items_query_args', $args, $request );\n\n\t\t// null is the default values.\n\t\tforeach ( $args as $key => $value ) {\n\t\t\tif ( empty( $value ) ) {\n\t\t\t\t$args[ $key ] = null;\n\t\t\t}\n\t\t}\n\n\t\t// Check if user is valid.\n\t\t$user = get_user_by( 'id', $request->get_param( 'user_id' ) );\n\t\tif ( ! $user instanceof WP_User ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_get_items_user_failed',\n\t\t\t\t__( 'There was a problem confirming if user is valid.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Actually, query it.\n\t\t$friendships = BP_Friends_Friendship::get_friendships( $user->ID, $args );\n\n\t\t$retval = array();\n\t\tforeach ( (array) $friendships as $friendship ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $friendship, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, count( $friendships ), $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after friendships are fetched via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array            $friendships Fetched friendships.\n\t\t * @param WP_REST_Response $response    The response data.\n\t\t * @param WP_REST_Request  $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_friends_get_items', $friendships, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to friendship items.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the friends `get_items` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve single friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$user = get_user_by( 'id', $request->get_param( 'id' ) );\n\n\t\t// Check if user is valid.\n\t\tif ( false === $user ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_get_item_failed',\n\t\t\t\t__( 'There was a problem confirming if user is valid.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get friendship.\n\t\t$friendship = $this->get_friendship_object(\n\t\t\tBP_Friends_Friendship::get_friendship_id( bp_loggedin_user_id(), $user->ID )\n\t\t);\n\n\t\tif ( ! $friendship || empty( $friendship->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Friendship does not exist.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $friendship, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires before a friendship is retrieved via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Friends_Friendship $friendship  The friendship object.\n\t\t * @param WP_REST_Response      $response    The response data.\n\t\t * @param WP_REST_Request       $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_friends_get_item', $friendship, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get a friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the friendship `get_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Create a new friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$initiator_id = get_user_by( 'id', $request->get_param( 'initiator_id' ) );\n\t\t$friend_id    = get_user_by( 'id', $request->get_param( 'friend_id' ) );\n\n\t\t// Check if users are valid.\n\t\tif ( ! $initiator_id || ! $friend_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_create_item_failed',\n\t\t\t\t__( 'There was a problem confirming if user is valid.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Check if users are friends or if there is a friendship request.\n\t\tif ( 'not_friends' !== friends_check_friendship_status( $initiator_id->ID, $friend_id->ID ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_create_item_failed',\n\t\t\t\t__( 'Those users are already friends or have sent friendship request(s) recently.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$is_moderator    = bp_current_user_can( 'bp_moderate' );\n\t\t$current_user_id = bp_loggedin_user_id();\n\n\t\t/**\n\t\t * - Only admins can create friendship requests for other people.\n\t\t * - Admins can't create friendship requests to themselves from other people.\n\t\t * - Users can't create friendship requests to themselves from other people.\n\t\t */\n\t\tif (\n\t\t\t( $current_user_id !== $initiator_id->ID && ! $is_moderator )\n\t\t\t|| ( $current_user_id === $friend_id->ID && $is_moderator )\n\t\t\t|| ( ! in_array( $current_user_id, array( $initiator_id->ID, $friend_id->ID ), true ) && ! $is_moderator )\n\t\t) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_create_item_failed',\n\t\t\t\t__( 'You are not allowed to perform this action.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 403,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Only admins can force a friendship request.\n\t\t$force = ( true === $request->get_param( 'force' ) && $is_moderator );\n\n\t\t// Adding friendship.\n\t\tif ( ! friends_add_friend( $initiator_id->ID, $friend_id->ID, $force ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_create_item_failed',\n\t\t\t\t__( 'There was an error trying to create the friendship.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get friendship.\n\t\t$friendship = $this->get_friendship_object(\n\t\t\tBP_Friends_Friendship::get_friendship_id( $initiator_id->ID, $friend_id->ID )\n\t\t);\n\n\t\tif ( ! $friendship || empty( $friendship->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Friendship does not exist.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $friendship, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a friendship is created via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Friends_Friendship $friendship The friendship object.\n\t\t * @param WP_REST_Response      $retval     The response data.\n\t\t * @param WP_REST_Request       $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_friends_create_item', $friendship, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to create a friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the friends `create_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update, accept, friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t$user = get_user_by( 'id', $request->get_param( 'id' ) );\n\n\t\t// Check if user is valid.\n\t\tif ( false === $user ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_update_item_failed',\n\t\t\t\t__( 'There was a problem confirming if user is valid.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get friendship.\n\t\t$friendship = $this->get_friendship_object(\n\t\t\tBP_Friends_Friendship::get_friendship_id( bp_loggedin_user_id(), $user->ID )\n\t\t);\n\n\t\tif ( ! $friendship || empty( $friendship->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid friendship ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Accept friendship.\n\t\tif ( false === friends_accept_friendship( $friendship->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_cannot_update_item',\n\t\t\t\t__( 'Could not accept friendship.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Getting new, updated, friendship object.\n\t\t$friendship = $this->get_friendship_object( $friendship->id );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $friendship, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a friendship is updated via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Friends_Friendship $friendship Friendship object.\n\t\t * @param WP_REST_Response      $response   The response data.\n\t\t * @param WP_REST_Request       $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_friends_update_item', $friendship, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the friendship `update_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Reject/withdraw/remove friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$user = get_user_by( 'id', $request->get_param( 'id' ) );\n\n\t\t// Check if user is valid.\n\t\tif ( false === $user ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_delete_item_failed',\n\t\t\t\t__( 'There was a problem confirming if user is valid.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get friendship.\n\t\t$friendship = $this->get_friendship_object(\n\t\t\tBP_Friends_Friendship::get_friendship_id( bp_loggedin_user_id(), $user->ID )\n\t\t);\n\n\t\tif ( ! $friendship || empty( $friendship->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid friendship ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$previous = $this->prepare_item_for_response( $friendship, $request );\n\n\t\t// Remove a friendship.\n\t\tif ( true === $request->get_param( 'force' ) ) {\n\t\t\t$deleted = friends_remove_friend( $friendship->initiator_user_id, $friendship->friend_user_id );\n\n\t\t\t/**\n\t\t\t * If this change is being initiated by the initiator,\n\t\t\t * use the `reject` function.\n\t\t\t *\n\t\t\t * This is the user who requested the friendship, and is doing the withdrawing.\n\t\t\t */\n\t\t} elseif ( bp_loggedin_user_id() === $friendship->initiator_user_id ) {\n\t\t\t$deleted = friends_withdraw_friendship( $friendship->initiator_user_id, $friendship->friend_user_id );\n\t\t} else {\n\t\t\t/**\n\t\t\t * Otherwise, this change is being initiated by the user, friend,\n\t\t\t * who received the friendship reject.\n\t\t\t */\n\t\t\t$deleted = friends_reject_friendship( $friendship->id );\n\t\t}\n\n\t\tif ( false === $deleted ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_friends_cannot_delete_item',\n\t\t\t\t__( 'Could not delete friendship.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a friendship is deleted via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Friends_Friendship $friendship Friendship object.\n\t\t * @param WP_REST_Response      $response   The response data.\n\t\t * @param WP_REST_Request       $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_friends_delete_item', $friendship, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a friendship.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the friendship `delete_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares friendship data to return as an object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param BP_Friends_Friendship $friendship Friendship object.\n\t * @param WP_REST_Request       $request    Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $friendship, $request ) {\n\t\t$data = array(\n\t\t\t'id'               => (int) $friendship->id,\n\t\t\t'initiator_id'     => (int) $friendship->initiator_user_id,\n\t\t\t'friend_id'        => (int) $friendship->friend_user_id,\n\t\t\t'is_confirmed'     => (bool) $friendship->is_confirmed,\n\t\t\t'date_created'     => bp_rest_prepare_date_response( $friendship->date_created, get_date_from_gmt( $friendship->date_created ) ),\n\t\t\t'date_created_gmt' => bp_rest_prepare_date_response( $friendship->date_created ),\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $friendship ) );\n\n\t\t/**\n\t\t * Filter a friendship value returned from the API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param WP_REST_Response      $response   Response generated by the request.\n\t\t * @param WP_REST_Request       $request    Request used to generate the response.\n\t\t * @param BP_Friends_Friendship $friendship The friendship object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_prepare_value', $response, $request, $friendship );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param BP_Friends_Friendship $friendship Friendship object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $friendship ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $friendship->id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t\t'initiator'  => array(\n\t\t\t\t'href'       => bp_rest_get_object_url( $friendship->initiator_user_id, 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t),\n\t\t\t'friend'     => array(\n\t\t\t\t'href'       => bp_rest_get_object_url( $friendship->friend_user_id, 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t),\n\t\t);\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array                 $links      The prepared links of the REST response.\n\t\t * @param BP_Friends_Friendship $friendship Friendship object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_prepare_links', $links, $friendship );\n\t}\n\n\t/**\n\t * Get friendship object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param int $friendship_id Friendship ID.\n\t * @return BP_Friends_Friendship\n\t */\n\tpublic function get_friendship_object( $friendship_id ) {\n\t\treturn new BP_Friends_Friendship( (int) $friendship_id );\n\t}\n\n\t/**\n\t * Edit some arguments for the endpoint's methods.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args    = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$context = 'view';\n\n\t\t$args['id']['required']    = true;\n\t\t$args['id']['description'] = __( 'A unique numeric ID of a user.', 'buddypress' );\n\n\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key = 'update_item';\n\n\t\t\tunset( $args['initiator_id'] );\n\t\t\tunset( $args['friend_id'] );\n\t\t} elseif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\n\t\t\t// Remove the ID for POST requests since it is not available.\n\t\t\tunset( $args['id'] );\n\n\t\t\t// Those fields are required.\n\t\t\t$args['initiator_id']['required'] = true;\n\t\t\t$args['friend_id']['required']    = true;\n\n\t\t\t// This one is optional.\n\t\t\t$args['force'] = array(\n\t\t\t\t'description'       => __( 'Whether to force the friendship agreement.', 'buddypress' ),\n\t\t\t\t'default'           => false,\n\t\t\t\t'type'              => 'boolean',\n\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\n\t\t\t// This one is optional.\n\t\t\t$args['force'] = array(\n\t\t\t\t'description'       => __( 'Whether to force friendship removal.', 'buddypress' ),\n\t\t\t\t'default'           => false,\n\t\t\t\t'type'              => 'boolean',\n\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t\tunset( $args['initiator_id'] );\n\t\t\tunset( $args['friend_id'] );\n\t\t} elseif ( WP_REST_Server::READABLE === $method ) {\n\t\t\t$key = 'get_item';\n\n\t\t\t$args['id']['required'] = true;\n\n\t\t\t// Removing those args from the GET request.\n\t\t\tunset( $args['initiator_id'] );\n\t\t\tunset( $args['friend_id'] );\n\t\t}\n\n\t\tif ( 'get_item' !== $key ) {\n\t\t\t$context = 'edit';\n\t\t}\n\n\t\t$args = array_merge(\n\t\t\tarray(\n\t\t\t\t'context' => $this->get_context_param(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'default' => $context,\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t),\n\t\t\t$args\n\t\t);\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_friends_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the friends schema, conforming to JSON Schema.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_friends',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'               => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Unique numeric identifier of the friendship.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'initiator_id'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The unique numeric identifier of the user who is requesting the Friendship.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'friend_id'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The unique numeric identifier of the user who is invited to agree to the Friendship request.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'is_confirmed'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the friendship been confirmed/accepted.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t\t'date_created'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the friendship was created, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_created_gmt' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the friendship was created, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the friends schema.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for friends collections.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\tunset( $params['search'] );\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'ID of the member whose friendships are being retrieved.', 'buddypress' ),\n\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t'type'              => 'integer',\n\t\t\t'required'          => true,\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['is_confirmed'] = array(\n\t\t\t'description'       => __( 'Wether the friendship has been accepted.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['id'] = array(\n\t\t\t'description'       => __( 'Unique numeric identifier of the friendship.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['initiator_id'] = array(\n\t\t\t'description'       => __( 'The ID of the user who is requesting the Friendship.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['friend_id'] = array(\n\t\t\t'description'       => __( 'The ID of the user who is invited to agree to the Friendship request.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['order_by'] = array(\n\t\t\t'description'       => __( 'Column name to order the results by.', 'buddypress' ),\n\t\t\t'default'           => 'date_created',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'date_created', 'initiator_user_id', 'friend_user_id', 'id' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['order'] = array(\n\t\t\t'description'       => __( 'Order results ascending or descending.', 'buddypress' ),\n\t\t\t'default'           => 'desc',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'asc', 'desc' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_friends_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-groups/classes/class-bp-rest-attachments-group-avatar-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Attachments_Group_Avatar_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Group Avatar endpoints.\n *\n * @since 0.1.0\n */\nclass BP_REST_Attachments_Group_Avatar_Endpoint extends WP_REST_Controller {\n\tuse BP_REST_Attachments;\n\n\t/**\n\t * Reuse some parts of the BP_REST_Groups_Endpoint class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_Groups_Endpoint\n\t */\n\tprotected $groups_endpoint;\n\n\t/**\n\t * BP_Attachment_Avatar Instance.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_Attachment_Avatar\n\t */\n\tprotected $avatar_instance;\n\n\t/**\n\t * Hold the group object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_Groups_Group\n\t */\n\tprotected $group;\n\n\t/**\n\t * Group object type.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var string\n\t */\n\tprotected $object = 'group';\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Groups_Avatar_REST_Controller' );\n\n\t\t$this->namespace       = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base       = buddypress()->groups->id;\n\t\t$this->groups_endpoint = new BP_REST_Groups_Endpoint();\n\t\t$this->avatar_instance = new BP_Attachment_Avatar();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<group_id>[\\d]+)/avatar',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'group_id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_item_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Fetch an existing group avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$args = array();\n\n\t\tforeach ( array( 'full', 'thumb' ) as $type ) {\n\t\t\t$args[ $type ] = bp_core_fetch_avatar(\n\t\t\t\tarray(\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t\t'type'    => $type,\n\t\t\t\t\t'item_id' => (int) $this->group->id,\n\t\t\t\t\t'html'    => (bool) $request->get_param( 'html' ),\n\t\t\t\t\t'alt'     => $request->get_param( 'alt' ),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get the avatar object.\n\t\t$avatar = $this->get_avatar_object( $args );\n\n\t\tif ( ! $avatar->full && ! $avatar->thumb ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_avatar_no_image',\n\t\t\t\t__( 'Sorry, there was a problem fetching this group avatar.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $avatar, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group avatar is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param string            $avatar   The group avatar.\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_group_avatar_get_item', $avatar, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to get a group avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you cannot view group details.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 404 )\n\t\t\t);\n\n\t\t\t$this->group = $this->groups_endpoint->get_group_object( $request );\n\n\t\t\tif ( false !== $this->group ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group avatar `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_avatar_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Upload a group avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the image file from $_FILES.\n\t\t$files = $request->get_file_params();\n\n\t\tif ( empty( $files ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_avatar_no_image_file',\n\t\t\t\t__( 'Sorry, you need an image file to upload.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Upload the avatar.\n\t\t$avatar = $this->upload_avatar_from_file( $files );\n\t\tif ( is_wp_error( $avatar ) ) {\n\t\t\treturn $avatar;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $avatar, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group avatar is uploaded via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param stdClass          $avatar   The group avatar object.\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_group_avatar_create_item', $avatar, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to upload a group avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\tif ( ! is_wp_error( $retval ) ) {\n\t\t\tif ( bp_disable_group_avatar_uploads() || false === buddypress()->avatar->show_avatars ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_attachments_group_avatar_disabled',\n\t\t\t\t\t__( 'Sorry, group avatar upload is disabled.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 500,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( groups_is_user_admin( bp_loggedin_user_id(), $this->group->id ) || current_user_can( 'bp_moderate' ) ) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group avatar `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_avatar_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete an existing group avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$group_id = (int) $this->group->id;\n\n\t\tif ( ! bp_get_group_has_avatar( $group_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_avatar_no_uploaded_avatar',\n\t\t\t\t__( 'Sorry, there are no uploaded avatars for this group on this site.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$args = array();\n\n\t\tforeach ( array( 'full', 'thumb' ) as $type ) {\n\t\t\t$args[ $type ] = bp_core_fetch_avatar(\n\t\t\t\tarray(\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t\t'type'    => $type,\n\t\t\t\t\t'item_id' => $group_id,\n\t\t\t\t\t'html'    => false,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get the avatar object before deleting it.\n\t\t$avatar = $this->get_avatar_object( $args );\n\n\t\t$deleted = bp_core_delete_existing_avatar(\n\t\t\tarray(\n\t\t\t\t'object'  => $this->object,\n\t\t\t\t'item_id' => $group_id,\n\t\t\t)\n\t\t);\n\n\t\tif ( ! $deleted ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_avatar_delete_failed',\n\t\t\t\t__( 'Sorry, there was a problem deleting this group avatar.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $avatar,\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a group avatar is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_group_avatar_delete_item', $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to delete a group avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->create_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the group avatar `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_avatar_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares avatar data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param stdClass|string $avatar  Avatar object or string with url or image with html.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $avatar, $request ) {\n\t\t$data = array(\n\t\t\t'full'  => $avatar->full,\n\t\t\t'thumb' => $avatar->thumb,\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t/**\n\t\t * Filter a group avatar value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response  $response Response.\n\t\t * @param WP_REST_Request   $request  Request used to generate the response.\n\t\t * @param stdClass|string   $avatar   Avatar object or string with url or image with html.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_avatar_prepare_value', $response, $request, $avatar );\n\t}\n\n\t/**\n\t * Get the plugin schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_attachments_group_avatar',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'full'  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Full size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'thumb' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Thumb size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the attachments group avatar schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_avatar_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for the `get_item`.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t// Removing unused params.\n\t\tunset( $params['search'], $params['page'], $params['per_page'] );\n\n\t\t$params['html'] = array(\n\t\t\t'description'       => __( 'Whether to return an <img> HTML element, vs a raw URL to a group avatar.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['alt'] = array(\n\t\t\t'description'       => __( 'The alt attribute for the <img> element.', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the item collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_avatar_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-groups/classes/class-bp-rest-attachments-group-cover-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Attachments_Group_Cover_Endpoint class\n *\n * @package BuddyPress\n * @since 6.0.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Group Cover endpoints.\n *\n * /groups/<group_id>/cover\n *\n * @since 6.0.0\n */\nclass BP_REST_Attachments_Group_Cover_Endpoint extends WP_REST_Controller {\n\tuse BP_REST_Attachments;\n\n\t/**\n\t * BP_Attachment_Cover_Image Instance.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var BP_Attachment_Cover_Image\n\t */\n\tprotected $attachment_instance;\n\n\t/**\n\t * Reuse some parts of the BP_REST_Groups_Endpoint class.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var BP_REST_Groups_Endpoint\n\t */\n\tprotected $groups_endpoint;\n\n\t/**\n\t * Hold the group object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var BP_Groups_Group\n\t */\n\tprotected $group;\n\n\t/**\n\t * Group object type.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var string\n\t */\n\tprotected $object = 'group';\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Groups_Cover_REST_Controller' );\n\n\t\t$this->namespace           = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base           = buddypress()->groups->id;\n\t\t$this->groups_endpoint     = new BP_REST_Groups_Endpoint();\n\t\t$this->attachment_instance = new BP_Attachment_Cover_Image();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<group_id>[\\d]+)/cover',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'group_id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Fetch an existing group cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$cover_url = bp_get_group_cover_url( $this->group );\n\n\t\tif ( empty( $cover_url ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_cover_no_image',\n\t\t\t\t__( 'Sorry, there was a problem fetching this group cover.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $cover_url, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group cover is fetched via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param string            $cover_url  The group cover url.\n\t\t * @param WP_REST_Response  $response   The response data.\n\t\t * @param WP_REST_Request   $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_group_cover_get_item', $cover_url, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to get a group cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you cannot view group details.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 404 )\n\t\t\t);\n\n\t\t\t$this->group = $this->groups_endpoint->get_group_object( $request );\n\n\t\t\tif ( false !== $this->group && $this->groups_endpoint->can_see( $this->group ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group cover `get_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_cover_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Upload a group cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the image file from $_FILES.\n\t\t$files = $request->get_file_params();\n\n\t\tif ( empty( $files ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_cover_no_image_file',\n\t\t\t\t__( 'Sorry, you need an image file to upload.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Upload the group cover.\n\t\t$cover_url = $this->upload_cover_from_file( $files );\n\t\tif ( is_wp_error( $cover_url ) ) {\n\t\t\treturn $cover_url;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $cover_url, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group cover is uploaded via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param string            $cover_url  The group cover url.\n\t\t * @param WP_REST_Response  $response   The response data.\n\t\t * @param WP_REST_Request   $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_group_cover_create_item', $cover_url, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to upload a group cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = $this->delete_item_permissions_check( $request );\n\n\t\tif ( ! is_wp_error( $retval ) && bp_disable_group_cover_image_uploads() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_cover_disabled',\n\t\t\t\t__( 'Sorry, group cover upload is disabled.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the group cover `create_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_cover_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete an existing group cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$cover_url = bp_get_group_cover_url( $this->group );\n\t\t$deleted   = bp_attachments_delete_file(\n\t\t\tarray(\n\t\t\t\t'item_id'    => (int) $this->group->id,\n\t\t\t\t'object_dir' => $this->get_cover_object_component(),\n\t\t\t\t'type'       => 'cover-image',\n\t\t\t)\n\t\t);\n\n\t\tif ( ! $deleted ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_group_cover_delete_failed',\n\t\t\t\t__( 'Sorry, there was a problem deleting this group cover.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $cover_url,\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a group cover is deleted via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Groups_Group   $group     The group object.\n\t\t * @param WP_REST_Response  $response  The response data.\n\t\t * @param WP_REST_Request   $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_group_cover_delete_item', $this->group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to delete a group cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\tif ( ! is_wp_error( $retval ) ) {\n\t\t\t$args  = array();\n\t\t\t$error = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tif ( ! isset( $this->group->id ) || ! isset( $this->object ) ) {\n\t\t\t\t$retval = $error;\n\t\t\t} else {\n\t\t\t\t$args = array(\n\t\t\t\t\t'item_id' => (int) $this->group->id,\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t);\n\n\t\t\t\tif ( ! is_user_logged_in() ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t\t__( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_attachments_current_user_can( 'edit_cover_image', $args ) ) {\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = $error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group cover `delete_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_cover_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares group cover to return as an object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param string          $cover_url Group cover url.\n\t * @param WP_REST_Request $request   Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $cover_url, $request ) {\n\t\t$data = array(\n\t\t\t'image' => $cover_url,\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t/**\n\t\t * Filter a group cover value returned from the API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param WP_REST_Response  $response  Response.\n\t\t * @param WP_REST_Request   $request   Request used to generate the response.\n\t\t * @param string            $cover_url Group cover url.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_cover_prepare_value', $response, $request, $cover_url );\n\t}\n\n\t/**\n\t * Get the plugin schema, conforming to JSON Schema.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_attachments_group_cover',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'image' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Full size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the attachments group cover schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_group_cover_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-groups/classes/class-bp-rest-group-invites-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Group_Invites_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Group Invites endpoints.\n *\n * Use /groups/{group_id}/invites\n * Use /groups/{group_id}/invites/{invite_id}\n *\n * @since 0.1.0\n */\nclass BP_REST_Group_Invites_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Reuse some parts of the BP_REST_Groups_Endpoint class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_Groups_Endpoint\n\t */\n\tprotected $groups_endpoint;\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Groups_Invite_REST_Controller' );\n\n\t\t$this->namespace              = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base              = buddypress()->groups->id . '/invites';\n\t\t$this->groups_endpoint        = new BP_REST_Groups_Endpoint();\n\t\t$this->group_members_endpoint = new BP_REST_Group_Membership_Endpoint();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<invite_id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'invite_id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the group invitation.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'view' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve group invitations.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'item_id'     => $request->get_param( 'group_id' ),\n\t\t\t'user_id'     => $request->get_param( 'user_id' ),\n\t\t\t'invite_sent' => $request->get_param( 'invite_sent' ),\n\t\t\t'per_page'    => $request->get_param( 'per_page' ),\n\t\t\t'page'        => $request->get_param( 'page' ),\n\t\t);\n\n\t\t/**\n\t\t * Inviter_id is a special case, because 0 can be meaningful for requests,\n\t\t * but if it is zero for invitations, we can safely ignore it and should.\n\t\t * So, only apply non-zero inviter_ids.\n\t\t */\n\t\tif ( $request->get_param( 'inviter_id' ) ) {\n\t\t\t$args['inviter_id'] = $request->get_param( 'inviter_id' );\n\t\t}\n\n\t\t// If the query is not restricted by group, user or inviter, limit it to the current user, if not an admin.\n\t\tif ( ! $args['item_id'] && ! $args['user_id'] && ! $args['inviter_id'] && ! bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t$args['user_id'] = bp_loggedin_user_id();\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_group_invites_get_items_query_args', $args, $request );\n\n\t\t// Get invites.\n\t\t$invites_data = groups_get_invites( $args );\n\n\t\t$retval = array();\n\t\tforeach ( $invites_data as $invitation ) {\n\t\t\tif ( $invitation instanceof BP_Invitation ) {\n\t\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t\t$this->prepare_item_for_response( $invitation, $request )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, count( $invites_data ), $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a list of group invites are fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $invites_data  Invited users from the group.\n\t\t * @param WP_REST_Response $response      The response data.\n\t\t * @param WP_REST_Request  $request       The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_invites_get_items', $invites_data, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to group invitations.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return bool|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$error = new WP_Error(\n\t\t\t'bp_rest_group_invites_cannot_get_items',\n\t\t\t__( 'Sorry, you are not allowed to fetch group invitations with those arguments.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\t$retval = $error;\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$group_id        = (int) $request->get_param( 'group_id' );\n\t\t\t$current_user_id = (int) bp_loggedin_user_id();\n\t\t\t$user_id_arg     = (int) $request->get_param( 'user_id' );\n\t\t\t$inviter_id      = (int) $request->get_param( 'inviter_id' );\n\n\t\t\tif ( ! is_user_logged_in() ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you need to be logged in to see the group invitations.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( $group_id ) {\n\t\t\t\tif ( ! $user_id_arg ) {\n\t\t\t\t\t$user_id_arg = $current_user_id;\n\t\t\t\t}\n\n\t\t\t\t$user = bp_rest_get_user( $user_id_arg );\n\n\t\t\t\t// Check the user is valid.\n\t\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t$group = $this->groups_endpoint->get_group_object( $group_id );\n\n\t\t\t\t\t// Check the group is valid.\n\t\t\t\t\tif ( ! $group instanceof BP_Groups_Group ) {\n\t\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $this->can_see( $group->id ) ) {\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t* Users can see invitations if they\n\t\t\t\t\t\t* - are a site admin,\n\t\t\t\t\t\t* - are a group admin of the subject group (group_id must be specified).\n\t\t\t\t\t\t*/\n\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$retval = $error;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} elseif ( $user_id_arg ) {\n\t\t\t\t$user = bp_rest_get_user( $user_id_arg );\n\n\t\t\t\t// Check the user is valid.\n\t\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $user->ID === $current_user_id ) {\n\t\t\t\t\t/*\n\t\t\t\t\t* Users can see invitations if they:\n\t\t\t\t\t* - are a site admin,\n\t\t\t\t\t* - are the invite recipient (user_id must be specified).\n\t\t\t\t\t*/\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = $error;\n\t\t\t\t}\n\t\t\t} elseif ( $inviter_id ) {\n\t\t\t\t$inviter = bp_rest_get_user( $inviter_id );\n\n\t\t\t\t// Check the inviter is valid.\n\t\t\t\tif ( ! $inviter instanceof WP_User ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $inviter->ID === $current_user_id ) {\n\t\t\t\t\t/*\n\t\t\t\t\t* Users can see invitations if they:\n\t\t\t\t\t* - are a site admin,\n\t\t\t\t\t* - are the inviter (inviter_id must be specified).\n\t\t\t\t\t*/\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = $error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group invites `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Fetch a specific group invitation by ID.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$invite = $this->fetch_single_invite( $request->get_param( 'invite_id' ) );\n\t\t$retval = $this->prepare_response_for_collection(\n\t\t\t$this->prepare_item_for_response( $invite, $request )\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a membership request is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Invitation     $invite      Invitation object.\n\t\t * @param WP_REST_Response  $response    The response data.\n\t\t * @param WP_REST_Request   $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_invite_get_item', $invite, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to fetch group invitation.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$user_id = bp_loggedin_user_id();\n\n\t\t\tif ( ! $user_id ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you need to be logged in to see the group invitations.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$invite = $this->fetch_single_invite( $request->get_param( 'invite_id' ) );\n\n\t\t\t\tif ( ! $invite ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_invite_invalid_id',\n\t\t\t\t\t\t__( 'Invalid group invitation ID.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $this->can_see( $invite->item_id ) || in_array( $user_id, array( $invite->user_id, $invite->inviter_id ), true ) ) {\n\t\t\t\t\t/*\n\t\t\t\t\t* Users can see a specific invitation if they\n\t\t\t\t\t* - are a site admin\n\t\t\t\t\t* - are a group admin of the subject group\n\t\t\t\t\t* - are the invite recipient\n\t\t\t\t\t* - are the inviter\n\t\t\t\t\t*/\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_invites_cannot_get_item',\n\t\t\t\t\t\t__( 'Sorry, you are not allowed to fetch an invitation.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group membership request `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Invite a member to a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$inviter_id_arg = ! empty( $request->get_param( 'inviter_id' ) ) ? $request->get_param( 'inviter_id' ) : bp_loggedin_user_id();\n\t\t$group          = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\t\t$user           = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t$inviter        = bp_rest_get_user( $inviter_id_arg );\n\n\t\t$invite_id = groups_invite_user(\n\t\t\tarray(\n\t\t\t\t'user_id'     => $user->ID,\n\t\t\t\t'group_id'    => $group->id,\n\t\t\t\t'inviter_id'  => $inviter->ID,\n\t\t\t\t'send_invite' => ! empty( $request->get_param( 'invite_sent' ) ) ? (bool) $request->get_param( 'invite_sent' ) : 1,\n\t\t\t\t'content'     => $request->get_param( 'message' ),\n\t\t\t)\n\t\t);\n\n\t\tif ( ! $invite_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_invite_cannot_create_item',\n\t\t\t\t__( 'Could not invite member to the group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$invite = new BP_Invitation( $invite_id );\n\n\t\t// Set context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $invite, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a member is invited to a group via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Invitation    $invite         The invitation object.\n\t\t * @param WP_User          $user           The invited user.\n\t\t * @param WP_User          $inviter        The inviter user.\n\t\t * @param BP_Groups_Group  $group          The group object.\n\t\t * @param WP_REST_Response $response       The response data.\n\t\t * @param WP_REST_Request  $request        The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_invites_create_item', $invite, $user, $inviter, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to invite a member to a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$inviter_id_arg = ! empty( $request->get_param( 'inviter_id' ) ) ? $request->get_param( 'inviter_id' ) : bp_loggedin_user_id();\n\t\t$retval         = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to create an invitation.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\t$user    = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t\t$inviter = bp_rest_get_user( $inviter_id_arg );\n\n\t\t\tif ( empty( $user->ID ) || empty( $inviter->ID ) || $user->ID === $inviter->ID ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\t\t\tif ( empty( $group->id ) ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || bp_loggedin_user_id() === $inviter_id_arg ) {\n\t\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_invite_cannot_create_item',\n\t\t\t\t\t\t__( 'Sorry, you are not allowed to create the invitation as requested.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group invites `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Accept a group invitation.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$invite = $this->fetch_single_invite( $request->get_param( 'invite_id' ) );\n\t\t$accept = groups_accept_invite( $invite->user_id, $invite->item_id );\n\t\tif ( ! $accept ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_invite_cannot_update_item',\n\t\t\t\t__( 'Could not accept group invitation.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$accepted_member = new BP_Groups_Member( $invite->user_id, $invite->item_id );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->group_members_endpoint->prepare_item_for_response( $accepted_member, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$group    = $this->groups_endpoint->get_group_object( $invite->item_id );\n\n\t\t/**\n\t\t * Fires after a group invite is accepted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Groups_Member $accepted_member Accepted group member.\n\t\t * @param BP_Groups_Group  $group           The group object.\n\t\t * @param WP_REST_Response $response        The response data.\n\t\t * @param WP_REST_Request  $request         The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_invites_update_item', $accepted_member, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to accept a group invitation.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval  = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$user_id = bp_loggedin_user_id();\n\n\t\tif ( ! $user_id ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to see the group invitations.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\t$invite = $this->fetch_single_invite( $request->get_param( 'invite_id' ) );\n\n\t\t\tif ( ! $invite ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_invite_invalid_id',\n\t\t\t\t\t__( 'Invalid group invitation ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $user_id === $invite->user_id ) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_invite_cannot_update_item',\n\t\t\t\t\t__( 'Sorry, you are not allowed to accept the invitation as requested.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group invites `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Remove (reject/delete) a group invitation.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$user_id = bp_loggedin_user_id();\n\t\t$invite  = $this->fetch_single_invite( $request->get_param( 'invite_id' ) );\n\n\t\t// Set the invite response before it is deleted.\n\t\t$previous = $this->prepare_item_for_response( $invite, $request );\n\n\t\t/**\n\t\t * If this change is being initiated by the invited user,\n\t\t * use the `reject` function.\n\t\t */\n\t\tif ( $user_id === $invite->user_id ) {\n\t\t\t$deleted = groups_reject_invite( $invite->user_id, $invite->item_id, $invite->inviter_id );\n\t\t\t/**\n\t\t\t * Otherwise, this change is being initiated by a group admin, site admin,\n\t\t\t * or the inviter, and we should use the `uninvite` function.\n\t\t\t */\n\t\t} else {\n\t\t\t$deleted = groups_uninvite_user( $invite->user_id, $invite->item_id, $invite->inviter_id );\n\t\t}\n\n\t\tif ( ! $deleted ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_invite_cannot_delete_item',\n\t\t\t\t__( 'Could not delete group invitation.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t$user  = bp_rest_get_user( $invite->user_id );\n\t\t$group = $this->groups_endpoint->get_group_object( $invite->item_id );\n\n\t\t/**\n\t\t * Fires after a group invite is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_User          $user     The invited user.\n\t\t * @param BP_Groups_Group  $group    The group object.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_invites_delete_item', $user, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a group invitation.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return bool|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval  = true;\n\t\t$user_id = bp_loggedin_user_id();\n\t\t$invite  = $this->fetch_single_invite( $request->get_param( 'invite_id' ) );\n\n\t\tif ( ! $user_id ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to see the group invitations.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( true === $retval && ! $invite ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_invite_invalid_id',\n\t\t\t\t__( 'Invalid group invitation ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// The inviter, the invitee, group admins, and site admins can all delete invites.\n\t\tif ( true === $retval\n\t\t\t&& ! bp_current_user_can( 'bp_moderate' )\n\t\t\t&& ! in_array( $user_id, array( $invite->user_id, $invite->inviter_id ), true )\n\t\t\t&& ! groups_is_user_admin( $user_id, $invite->item_id )\n\t\t\t) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_invite_cannot_delete_item',\n\t\t\t\t__( 'Sorry, you are not allowed to delete the invitation as requested.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the group invites `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares group invitation data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Invitation   $invite  The invitation object.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $invite, $request ) {\n\t\t$data = array(\n\t\t\t'id'                => (int) $invite->id,\n\t\t\t'user_id'           => (int) $invite->user_id,\n\t\t\t'invite_sent'       => (int) $invite->invite_sent,\n\t\t\t'inviter_id'        => (int) $invite->inviter_id,\n\t\t\t'group_id'          => (int) $invite->item_id,\n\t\t\t'date_modified'     => bp_rest_prepare_date_response( $invite->date_modified, get_date_from_gmt( $invite->date_modified ) ),\n\t\t\t'date_modified_gmt' => bp_rest_prepare_date_response( $invite->date_modified ),\n\t\t\t'type'              => (string) $invite->type,\n\t\t\t'message'           => array(\n\t\t\t\t'raw'      => $invite->content,\n\t\t\t\t'rendered' => apply_filters( 'the_content', $invite->content ),\n\t\t\t),\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $invite ) );\n\n\t\t/**\n\t\t * Filter a group invite value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  Request used to generate the response.\n\t\t * @param BP_Invitation    $invite   The invitation object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_prepare_value', $response, $request, $invite );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Invitation $invite Invite object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $invite ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\t\t$url  = $base . $invite->id;\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $url ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t\t'user'       => array(\n\t\t\t\t'href'       => bp_rest_get_object_url( $invite->user_id, 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t),\n\t\t);\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array    $links  The prepared links of the REST response.\n\t\t * @param stdClass $invite Invite object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_prepare_links', $links, $invite );\n\t}\n\n\t/**\n\t * Check access.\n\t *\n\t * @param int $group_id Group ID.\n\t * @return bool\n\t */\n\tprotected function can_see( $group_id ) {\n\t\t$user_id = bp_loggedin_user_id();\n\n\t\tif ( ! groups_is_user_admin( $user_id, $group_id ) && ! groups_is_user_mod( $user_id, $group_id ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Helper function to fetch a single group invite.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $invite_id The ID of the invitation you wish to fetch.\n\t * @return BP_Invitation|bool $invite Invitation if found, false otherwise.\n\t */\n\tpublic function fetch_single_invite( $invite_id = 0 ) {\n\t\t$invites = groups_get_invites( array( 'id' => $invite_id ) );\n\t\tif ( $invites ) {\n\t\t\treturn current( $invites );\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Edit the type of the some properties for the CREATABLE & EDITABLE methods.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key                            = 'create_item';\n\t\t\t$args['message']['type']        = 'string';\n\t\t\t$args['message']['description'] = __( 'The optional message to send to the invited user.', 'buddypress' );\n\t\t\t$args['message']['default']     = '';\n\t\t\t$args['send_invite']            = $args['invite_sent'];\n\t\t\t$args['inviter_id']['default']  = bp_loggedin_user_id();\n\t\t\t$args['group_id']['required']   = true;\n\t\t\t$args['user_id']['required']    = true;\n\n\t\t\t// Remove arguments not needed for the CREATABLE transport method.\n\t\t\tunset( $args['message']['properties'], $args['invite_sent'], $args['date_modified'], $args['type'] );\n\n\t\t\t$args['send_invite']['description'] = __( 'Whether the invite should be sent to the invitee.', 'buddypress' );\n\t\t\t$args['send_invite']['default']     = true;\n\n\t\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t\t$key = 'update_item';\n\t\t\t}\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_group_invites_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the group invite schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_group_invites',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the BP Invitation object.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'user_id'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the user who is invited to join the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'invite_sent'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the invite has been sent to the invitee.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t\t'inviter_id'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the user who made the invite.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'group_id'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the group to which the user has been invited.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'date_modified'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the object was created or last updated, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_modified_gmt' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the object was created or last updated, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'type'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Invitation or request.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => array( 'invite', 'request' ),\n\t\t\t\t\t\t'default'     => 'invite',\n\t\t\t\t\t),\n\t\t\t\t\t'message'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The raw and rendered versions for the content of the message.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the object, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the object, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the group invites schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections of group invites.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t// Remove the search param.\n\t\tunset( $params['search'] );\n\n\t\t$params['group_id'] = array(\n\t\t\t'description'       => __( 'ID of the group to limit results to.', 'buddypress' ),\n\t\t\t'required'          => false,\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Return only invitations extended to this user.', 'buddypress' ),\n\t\t\t'required'          => false,\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['inviter_id'] = array(\n\t\t\t'description'       => __( 'Return only invitations extended by this user.', 'buddypress' ),\n\t\t\t'required'          => false,\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['invite_sent'] = array(\n\t\t\t'description'       => __( 'Limit result set to invites that have been sent, not sent, or include all.', 'buddypress' ),\n\t\t\t'default'           => 'sent',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t'enum'              => array( 'draft', 'sent', 'all' ),\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_invites_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-groups/classes/class-bp-rest-group-membership-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Group_Membership_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Group membership endpoints.\n *\n * Use /groups/{group_id}/members\n * Use /groups/{group_id}/members/{user_id}\n *\n * @since 0.1.0\n */\nclass BP_REST_Group_Membership_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Reuse some parts of the BP_REST_Groups_Endpoint class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_Groups_Endpoint\n\t */\n\tprotected $groups_endpoint;\n\n\t/**\n\t * Reuse some parts of the BP_REST_Members_Endpoint class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_Members_Endpoint\n\t */\n\tprotected $members_endpoint;\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Groups_Membership_REST_Controller' );\n\n\t\t$this->namespace        = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base        = buddypress()->groups->id;\n\t\t$this->groups_endpoint  = new BP_REST_Groups_Endpoint();\n\t\t$this->members_endpoint = new BP_REST_Members_Endpoint();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<group_id>[\\d]+)/members',\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_method( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<group_id>[\\d]+)/members/(?P<user_id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_method( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_method( WP_REST_Server::DELETABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve group members.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\t\t$args  = array(\n\t\t\t'group_id'            => $group->id,\n\t\t\t'group_role'          => $request->get_param( 'roles' ),\n\t\t\t'type'                => $request->get_param( 'status' ),\n\t\t\t'per_page'            => $request->get_param( 'per_page' ),\n\t\t\t'page'                => $request->get_param( 'page' ),\n\t\t\t'search_terms'        => $request->get_param( 'search' ),\n\t\t\t'exclude'             => $request->get_param( 'exclude' ),\n\t\t\t'exclude_admins_mods' => (bool) $request->get_param( 'exclude_admins' ),\n\t\t\t'exclude_banned'      => (bool) $request->get_param( 'exclude_banned' ),\n\t\t);\n\n\t\tif ( empty( $args['exclude'] ) ) {\n\t\t\t$args['exclude'] = false;\n\t\t}\n\n\t\tif ( is_null( $args['search_terms'] ) ) {\n\t\t\t$args['search_terms'] = false;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_group_members_get_items_query_args', $args, $request );\n\n\t\t// Get our members.\n\t\t$members = groups_get_group_members( $args );\n\n\t\t$retval = array();\n\t\tforeach ( $members['members'] as $member ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $member, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $members['count'], $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a list of group members are fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $members  Fetched group members.\n\t\t * @param BP_Groups_Group  $group    The group object.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_members_get_items', $members, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to group members.\n\t *\n\t * We are using the same permissions check done on group access.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you cannot view the group.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\t\t\tif ( empty( $group->id ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || 'public' === $group->status || groups_is_user_member( bp_loggedin_user_id(), $group->id ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group members `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Add member to a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$user  = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\tif ( ! $request->get_param( 'context' ) || 'view' === $request->get_param( 'context' ) ) {\n\t\t\tif ( ! groups_join_group( $group->id, $user->ID ) ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_failed_to_join',\n\t\t\t\t\t__( 'Could not join the group.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 500,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Get the group member.\n\t\t\t$group_member = new BP_Groups_Member( $user->ID, $group->id );\n\t\t} else {\n\t\t\t$role         = $request->get_param( 'role' );\n\t\t\t$group_id     = $group->id;\n\t\t\t$group_member = new BP_Groups_Member( $user->ID, $group_id );\n\n\t\t\t// Add member to the group.\n\t\t\t$group_member->group_id      = $group_id;\n\t\t\t$group_member->user_id       = $user->ID;\n\t\t\t$group_member->is_admin      = 0;\n\t\t\t$group_member->date_modified = bp_core_current_time();\n\t\t\t$group_member->is_confirmed  = 1;\n\t\t\t$saved                       = $group_member->save();\n\n\t\t\tif ( ! $saved ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_failed_to_join',\n\t\t\t\t\t__( 'Could not add member to the group.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 500,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// If new role set, promote it too.\n\t\t\tif ( $saved && 'member' !== $role ) {\n\t\t\t\t// Make sure to update the group role.\n\t\t\t\tif ( groups_promote_member( $user->ID, $group_id, $role ) ) {\n\t\t\t\t\t$group_member = new BP_Groups_Member( $user->ID, $group_id );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group_member, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a member is added to a group via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_User          $user         The user.\n\t\t * @param BP_Groups_Member $group_member The group member object.\n\t\t * @param BP_Groups_Group  $group        The group object.\n\t\t * @param WP_REST_Response $response     The response data.\n\t\t * @param WP_REST_Request  $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_members_create_item', $user, $group_member, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to join a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t);\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to join a group.', 'buddypress' ),\n\t\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t\t);\n\t\t} else {\n\t\t\t$user             = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t\t$loggedin_user_id = bp_loggedin_user_id();\n\n\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_invalid_id',\n\t\t\t\t\t__( 'Invalid group member ID.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\t\t\tif ( ! $group instanceof BP_Groups_Group ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || ( bp_current_user_can( 'groups_join_group', array( 'group_id' => $group->id ) ) && $loggedin_user_id === $user->ID ) ) {\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_member_failed_to_join',\n\t\t\t\t\t\t__( 'Could not join the group.', 'buddypress' ),\n\t\t\t\t\t\tarray( 'status' => 500 )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group members `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update user status on a group (add, remove, promote, demote or ban).\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t$user     = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t$group    = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\t\t$action   = $request->get_param( 'action' );\n\t\t$role     = $request->get_param( 'role' );\n\t\t$group_id = $group->id;\n\n\t\t$bp_loggedin_user_id = bp_loggedin_user_id();\n\n\t\t// Check if the user is a member of the group.\n\t\tif ( 'unban' !== $action && ! groups_is_user_member( $user->ID, $group_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_member_not_member',\n\t\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 500 )\n\t\t\t);\n\t\t}\n\n\t\tif ( 'promote' === $action ) {\n\t\t\tif ( ! groups_promote_member( $user->ID, $group_id, $role, $bp_loggedin_user_id ) ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_failed_to_promote',\n\t\t\t\t\t__( 'Could not promote member.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 500 )\n\t\t\t\t);\n\t\t\t}\n\t\t} elseif ( 'demote' === $action && 'member' !== $role ) {\n\t\t\tif ( ! groups_promote_member( $user->ID, $group_id, $role, $bp_loggedin_user_id ) ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_failed_to_demote',\n\t\t\t\t\t__( 'Could not demote member.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 500 )\n\t\t\t\t);\n\t\t\t}\n\t\t} elseif ( in_array( $action, array( 'demote', 'ban', 'unban' ), true ) ) {\n\t\t\tif ( ! call_user_func( 'groups_' . $action . '_member', $user->ID, $group_id, $bp_loggedin_user_id ) ) {\n\t\t\t\t$messages = array(\n\t\t\t\t\t'demote' => __( 'Could not demote member from the group.', 'buddypress' ),\n\t\t\t\t\t'ban'    => __( 'Could not ban member from the group.', 'buddypress' ),\n\t\t\t\t\t'unban'  => __( 'Could not unban member from the group.', 'buddypress' ),\n\t\t\t\t);\n\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_failed_to_' . $action,\n\t\t\t\t\t$messages[ $action ],\n\t\t\t\t\tarray( 'status' => 500 )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Get updated group member.\n\t\t$group_member = new BP_Groups_Member( $user->ID, $group_id );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group_member, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group member status is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_User          $user         The updated member.\n\t\t * @param BP_Groups_Member $group_member The group member object.\n\t\t * @param BP_Groups_Group  $group        The group object.\n\t\t * @param WP_REST_Response $response     The response data.\n\t\t * @param WP_REST_Request  $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_members_update_item', $user, $group_member, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a group member.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$error = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t);\n\n\t\t$admin_error = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Group needs 1 admin at least. Please promote a user before trying to remove this group admin.', 'buddypress' ),\n\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t);\n\n\t\t$retval = $error;\n\t\t$action = $request->get_param( 'action' );\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = $error;\n\t\t} else {\n\t\t\t$user             = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t\t$loggedin_user_id = bp_loggedin_user_id();\n\n\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_invalid_id',\n\t\t\t\t\t__( 'Invalid group member ID.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\t\t\tif ( ! $group instanceof BP_Groups_Group ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) && $loggedin_user_id !== $user->ID ) {\n\t\t\t\t\tif ( 'demote' === $action && groups_is_user_admin( $user->ID, $group->id ) ) {\n\t\t\t\t\t\t$group_admins = groups_get_group_admins( $group->id );\n\n\t\t\t\t\t\tif ( 1 !== count( $group_admins ) ) {\n\t\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$retval = $admin_error;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t}\n\t\t\t\t} elseif ( groups_is_user_admin( $loggedin_user_id, $group->id ) && $loggedin_user_id !== $user->ID ) {\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$messages = array(\n\t\t\t\t\t\t'ban'     => __( 'Sorry, you are not allowed to ban this group member.', 'buddypress' ),\n\t\t\t\t\t\t'unban'   => __( 'Sorry, you are not allowed to unban this group member.', 'buddypress' ),\n\t\t\t\t\t\t'promote' => __( 'Sorry, you are not allowed to promote this group member.', 'buddypress' ),\n\t\t\t\t\t\t'demote'  => __( 'Sorry, you are not allowed to demote this group member.', 'buddypress' ),\n\t\t\t\t\t);\n\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_member_cannot_' . $action,\n\t\t\t\t\t\t$messages[ $action ],\n\t\t\t\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group members `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete a group membership.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$group_id = $request->get_param( 'group_id' );\n\t\t$user_id  = $request->get_param( 'user_id' );\n\n\t\t// Get the Group member before it's removed.\n\t\t$member = new BP_Groups_Member( $user_id, $group_id );\n\n\t\tif ( ! $member->remove() ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_member_failed_to_remove',\n\t\t\t\t__( 'Could not remove member from this group.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 500 )\n\t\t\t);\n\t\t}\n\n\t\t$previous_member = $this->prepare_item_for_response( $member, $request );\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'removed'  => true,\n\t\t\t\t'previous' => $previous_member->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t$user  = bp_rest_get_user( $user_id );\n\t\t$group = $this->groups_endpoint->get_group_object( $group_id );\n\n\t\t/**\n\t\t * Fires after a group member is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_User          $user     The updated member.\n\t\t * @param BP_Groups_Member $member   The group member object.\n\t\t * @param BP_Groups_Group  $group    The group object.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_members_delete_item', $user, $member, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a group member.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$authorization_code = rest_authorization_required_code();\n\n\t\t$error = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray( 'status' => $authorization_code )\n\t\t);\n\n\t\t$admin_error = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Group needs 1 admin at least. Please promote a user before trying to remove this group admin.', 'buddypress' ),\n\t\t\tarray( 'status' => $authorization_code )\n\t\t);\n\n\t\t$retval = $error;\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to view a group membership.', 'buddypress' ),\n\t\t\t\tarray( 'status' => $authorization_code )\n\t\t\t);\n\t\t} else {\n\t\t\t$user             = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t\t$loggedin_user_id = bp_loggedin_user_id();\n\n\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_group_member_invalid_id',\n\t\t\t\t\t__( 'Invalid group member ID.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\t\t\tif ( ! $group instanceof BP_Groups_Group ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || ( groups_is_user_admin( $loggedin_user_id, $group->id ) && $loggedin_user_id !== $user->ID ) ) {\n\t\t\t\t\tif ( groups_is_user_admin( $user->ID, $group->id ) ) {\n\t\t\t\t\t\t$group_admins = groups_get_group_admins( $group->id );\n\n\t\t\t\t\t\tif ( 1 !== count( $group_admins ) ) {\n\t\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$retval = $admin_error;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t}\n\t\t\t\t} elseif ( $user->ID === $loggedin_user_id && ! groups_is_user_banned( $user->ID, $group->id ) ) {\n\t\t\t\t\tif ( groups_is_user_admin( $loggedin_user_id, $group->id ) ) {\n\t\t\t\t\t\t$group_admins = groups_get_group_admins( $group->id );\n\n\t\t\t\t\t\tif ( 1 !== count( $group_admins ) ) {\n\t\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$retval = $admin_error;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group members `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares group member data for return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Groups_Member $group_member Group member object.\n\t * @param WP_REST_Request  $request      Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $group_member, $request ) {\n\t\t$user                   = bp_rest_get_user( $group_member->user_id );\n\t\t$context                = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$member_data            = $this->members_endpoint->user_data( $user, $context, $request );\n\t\t$group_member->group_id = $request->get_param( 'group_id' );\n\t\t$date_modified          = $group_member->date_modified;\n\n\t\tif ( is_null( $date_modified ) ) {\n\t\t\t$date_modified = '';\n\t\t}\n\n\t\t// Merge both info.\n\t\t$data = array_merge(\n\t\t\t$member_data,\n\t\t\tarray(\n\t\t\t\t'group'             => (int) $group_member->group_id,\n\t\t\t\t'is_mod'            => (bool) $group_member->is_mod,\n\t\t\t\t'is_admin'          => (bool) $group_member->is_admin,\n\t\t\t\t'is_banned'         => (bool) $group_member->is_banned,\n\t\t\t\t'is_confirmed'      => (bool) $group_member->is_confirmed,\n\t\t\t\t'date_modified'     => bp_rest_prepare_date_response( $date_modified, get_date_from_gmt( $date_modified ) ),\n\t\t\t\t'date_modified_gmt' => bp_rest_prepare_date_response( $date_modified ),\n\t\t\t)\n\t\t);\n\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $group_member ) );\n\n\t\t/**\n\t\t * Filter a group member value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response $response      The response data.\n\t\t * @param WP_REST_Request  $request       Request used to generate the response.\n\t\t * @param BP_Groups_Member $group_member  The group member object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_prepare_value', $response, $request, $group_member );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Groups_Member $group_member Group member object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $group_member ) {\n\t\t$base = sprintf( '/%s/%s', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => bp_rest_get_object_url( $group_member->user_id, 'members' ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( sprintf( '/%s/%d/members', $base, $group_member->group_id ) ),\n\t\t\t),\n\t\t\t'group'      => array(\n\t\t\t\t'href'       => rest_url( sprintf( '/%s/%d', $base, $group_member->group_id ) ),\n\t\t\t\t'embeddable' => true,\n\t\t\t),\n\t\t);\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array $          links         The prepared links of the REST response.\n\t\t * @param BP_Groups_Member $group_member Group member object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_prepare_links', $links, $group_member );\n\t}\n\n\t/**\n\t * GET arguments for the endpoint's CREATABLE, EDITABLE & DELETABLE methods.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_method( $method = WP_REST_Server::CREATABLE ) {\n\t\t$key  = 'get_item';\n\t\t$args = array(\n\t\t\t'context' => $this->get_context_param(\n\t\t\t\tarray(\n\t\t\t\t\t'default' => 'edit',\n\t\t\t\t)\n\t\t\t),\n\t\t);\n\n\t\tif ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$group_roles = array_diff( array_keys( bp_groups_get_group_roles() ), array( 'banned' ) );\n\n\t\t\t$args['role'] = array(\n\t\t\t\t'description'       => __( 'Group role to assign the user to.', 'buddypress' ),\n\t\t\t\t'default'           => 'member',\n\t\t\t\t'type'              => 'string',\n\t\t\t\t'enum'              => $group_roles,\n\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t\t$key             = 'create_item';\n\t\t\t\t$schema          = $this->get_item_schema();\n\t\t\t\t$args['user_id'] = array_merge(\n\t\t\t\t\t$schema['properties']['id'],\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Member to add to the Group.', 'buddypress' ),\n\t\t\t\t\t\t'default'     => bp_loggedin_user_id(),\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'readonly'    => false,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t\t$key            = 'update_item';\n\t\t\t\t$args['action'] = array(\n\t\t\t\t\t'description'       => __( 'Action used to update a group member.', 'buddypress' ),\n\t\t\t\t\t'default'           => 'promote',\n\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t'enum'              => array( 'promote', 'demote', 'ban', 'unban' ),\n\t\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\t\t\t}\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array $args Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_group_members_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the group member schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\n\t\t\t// Get schema from members.\n\t\t\t$schema = $this->members_endpoint->get_item_schema();\n\n\t\t\t// Set title to this endpoint.\n\t\t\t$schema['title'] = 'bp_group_members';\n\n\t\t\t$schema['properties']['group_id'] = array(\n\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),\n\t\t\t\t'type'        => 'integer',\n\t\t\t);\n\n\t\t\t$schema['properties']['is_mod'] = array(\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t'description' => __( 'Whether the member is a group moderator.', 'buddypress' ),\n\t\t\t\t'type'        => 'boolean',\n\t\t\t);\n\n\t\t\t$schema['properties']['is_banned'] = array(\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t'description' => __( 'Whether the member has been banned from the group.', 'buddypress' ),\n\t\t\t\t'type'        => 'boolean',\n\t\t\t);\n\n\t\t\t$schema['properties']['is_admin'] = array(\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t'description' => __( 'Whether the member is a group administrator.', 'buddypress' ),\n\t\t\t\t'type'        => 'boolean',\n\t\t\t);\n\n\t\t\t$schema['properties']['is_confirmed'] = array(\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t'description' => __( 'Whether the membership of this user has been confirmed.', 'buddypress' ),\n\t\t\t\t'type'        => 'boolean',\n\t\t\t);\n\n\t\t\t$schema['properties']['date_modified'] = array(\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t'description' => __( 'The date of the last time the membership of this user was modified, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t'readonly'    => true,\n\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t'format'      => 'date-time',\n\t\t\t);\n\n\t\t\t$schema['properties']['date_modified_gmt'] = array(\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t'description' => __( 'The date of the last time the membership of this user was modified, as GMT.', 'buddypress' ),\n\t\t\t\t'readonly'    => true,\n\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t'format'      => 'date-time',\n\t\t\t);\n\n\t\t\t// Cache current schema here.\n\t\t\t$this->schema = $schema;\n\t\t}\n\n\t\t/**\n\t\t * Filters the group membership schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections of group memberships.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\t\t$statuses                     = array( 'last_joined', 'first_joined', 'alphabetical' );\n\n\t\tif ( bp_is_active( 'activity' ) ) {\n\t\t\t$statuses[] = 'group_activity';\n\t\t}\n\n\t\t$params['status'] = array(\n\t\t\t'description'       => __( 'Sort the order of results by the status of the group members.', 'buddypress' ),\n\t\t\t'default'           => 'last_joined',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => $statuses,\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['roles'] = array(\n\t\t\t'description'       => __( 'Ensure result set includes specific group roles.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array(\n\t\t\t\t'type' => 'string',\n\t\t\t\t'enum' => array_keys( bp_groups_get_group_roles() ),\n\t\t\t),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_string_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes specific member IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude_admins'] = array(\n\t\t\t'description'       => __( 'Whether results should exclude group admins and mods.', 'buddypress' ),\n\t\t\t'default'           => true,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude_banned'] = array(\n\t\t\t'description'       => __( 'Whether results should exclude banned group members.', 'buddypress' ),\n\t\t\t'default'           => true,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_members_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-groups/classes/class-bp-rest-group-membership-request-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Group_Membership_Request_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Group Membership Request Endpoint.\n *\n * Use /groups/{group_id}/membership-request\n * Use /groups/membership-request/{request_id}\n *\n * @since 0.1.0\n */\nclass BP_REST_Group_Membership_Request_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Reuse some parts of the BP_REST_Groups_Endpoint class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_Groups_Endpoint\n\t */\n\tprotected $groups_endpoint;\n\n\t/**\n\t * Reuse some parts of the BP_REST_Group_Invites_Endpoint class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_Group_Invites_Endpoint\n\t */\n\tprotected $invites_endpoint;\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Groups_Membership_Request_REST_Controller' );\n\n\t\t$this->namespace              = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base              = buddypress()->groups->id . '/membership-requests';\n\t\t$this->groups_endpoint        = new BP_REST_Groups_Endpoint();\n\t\t$this->group_members_endpoint = new BP_REST_Group_Membership_Endpoint();\n\t\t$this->invites_endpoint       = new BP_REST_Group_Invites_Endpoint();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<request_id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'request_id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the group membership request.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'view' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Fetch pending group membership requests.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'item_id'  => $request->get_param( 'group_id' ),\n\t\t\t'user_id'  => $request->get_param( 'user_id' ),\n\t\t\t'per_page' => $request->get_param( 'per_page' ),\n\t\t\t'page'     => $request->get_param( 'page' ),\n\t\t);\n\n\t\t// If the query is not restricted by group or user, limit it to the current user, if not an admin.\n\t\tif ( ! $args['item_id'] && ! $args['user_id'] && ! bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t$args['user_id'] = bp_loggedin_user_id();\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_group_membership_requests_get_items_query_args', $args, $request );\n\n\t\t$group_requests = groups_get_requests( $args );\n\n\t\t$retval = array();\n\t\tforeach ( $group_requests as $group_request ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group_request, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, count( $group_requests ), $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a list of group membership request is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array of BP_Invitations $group_requests List of membership requests.\n\t\t * @param WP_REST_Response        $response       The response data.\n\t\t * @param WP_REST_Request         $request        The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_membership_requests_get_items', $group_requests, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to fetch group membership requests.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$user_id     = bp_loggedin_user_id();\n\t\t\t$user_id_arg = $request->get_param( 'user_id' );\n\t\t\t$group       = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\t\t// If the query is not restricted by group or user, limit it to the current user, if not an admin.\n\t\t\tif ( ! $request->get_param( 'group_id' ) && ! $request->get_param( 'user_id' ) && ! bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t\t$user_id_arg = $user_id;\n\t\t\t}\n\t\t\t$user = bp_rest_get_user( $user_id_arg );\n\n\t\t\tif ( ! $user_id ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you need to be logged in to view membership requests.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( $request->get_param( 'group_id' ) && ! $group instanceof BP_Groups_Group ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( $user_id_arg && ! $user instanceof WP_User ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif (\n\t\t\t\tbp_current_user_can( 'bp_moderate' )\n\t\t\t\t|| ( $request->get_param( 'group_id' ) && groups_is_user_admin( $user_id, $request->get_param( 'group_id' ) ) )\n\t\t\t\t|| $user_id_arg === $user_id\n\t\t\t) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_membership_requests_cannot_get_items',\n\t\t\t\t\t__( 'Sorry, you are not allowed to view membership requests.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Fetch a sepcific pending group membership request by ID.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$group_request = $this->fetch_single_membership_request( $request->get_param( 'request_id' ) );\n\t\t$retval        = $this->prepare_response_for_collection(\n\t\t\t$this->prepare_item_for_response( $group_request, $request )\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a membership request is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Invitation     $group_request Membership request object.\n\t\t * @param WP_REST_Response  $response      The response data.\n\t\t * @param WP_REST_Request   $request       The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_membership_requests_get_item', $group_request, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to fetch group membership request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$user_id       = bp_loggedin_user_id();\n\t\t\t$group_request = $this->fetch_single_membership_request( $request->get_param( 'request_id' ) );\n\n\t\t\tif ( ! $user_id ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you need to be logged in to get a membership.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( ! $group_request ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_membership_requests_invalid_id',\n\t\t\t\t\t__( 'Invalid group membership request ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $user_id === $group_request->user_id || groups_is_user_admin( $user_id, $group_request->item_id ) ) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_membership_requests_cannot_get_item',\n\t\t\t\t\t__( 'Sorry, you are not allowed to view a membership request.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the group membership request `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Request membership to a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$user_id_arg = ! empty( $request->get_param( 'user_id' ) ) ? $request->get_param( 'user_id' ) : bp_loggedin_user_id();\n\t\t$user        = bp_rest_get_user( $user_id_arg );\n\t\t$group       = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\t// Avoid duplicate requests.\n\t\tif ( groups_check_for_membership_request( $user->ID, $group->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_membership_requests_duplicate_request',\n\t\t\t\t__( 'There is already a request to this member.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$request_id = groups_send_membership_request(\n\t\t\tarray(\n\t\t\t\t'group_id' => $group->id,\n\t\t\t\t'user_id'  => $user->ID,\n\t\t\t\t'content'  => $request->get_param( 'message' ),\n\t\t\t)\n\t\t);\n\n\t\tif ( ! $request_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_membership_requests_cannot_create_item',\n\t\t\t\t__( 'Could not send membership request to this group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$invite = new BP_Invitation( $request_id );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $invite, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group membership request is made via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_User          $user     The user.\n\t\t * @param BP_Invitation    $invite   The invitation object.\n\t\t * @param BP_Groups_Group  $group    The group object.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_membership_requests_create_item', $user, $invite, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to make a group membership request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval      = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$user_id     = bp_loggedin_user_id();\n\t\t$user_id_arg = ! empty( $request->get_param( 'user_id' ) ) ? $request->get_param( 'user_id' ) : $user_id;\n\t\t$user        = bp_rest_get_user( $user_id_arg );\n\t\t$group       = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );\n\n\t\t// User must be logged in.\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to create a membership request.', 'buddypress' ),\n\t\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t\t);\n\t\t} elseif ( ! $user instanceof WP_User ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_member_invalid_id',\n\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 404 )\n\t\t\t);\n\t\t} elseif ( ! $group instanceof BP_Groups_Group ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 404 )\n\t\t\t);\n\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $user_id === $user_id_arg ) {\n\t\t\t$retval = true;\n\t\t} else {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_membership_requests_cannot_create_item',\n\t\t\t\t__( 'User may not extend requests on behalf of another user.', 'buddypress' ),\n\t\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the group membership request `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Accept or reject a pending group membership request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t$group_request = $this->fetch_single_membership_request( $request->get_param( 'request_id' ) );\n\t\t$success       = groups_accept_membership_request( false, $group_request->user_id, $group_request->item_id );\n\t\tif ( ! $success ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_member_request_cannot_update_item',\n\t\t\t\t__( 'There was an error accepting the membership request.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$g_member = new BP_Groups_Member( $group_request->user_id, $group_request->item_id );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->group_members_endpoint->prepare_item_for_response( $g_member, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$group    = $this->groups_endpoint->get_group_object( $group_request->item_id );\n\n\t\t/**\n\t\t * Fires after a group membership request is accepted/rejected via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Groups_Member $g_member The groups member object.\n\t\t * @param BP_Groups_Group  $group    The group object.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_membership_requests_update_item', $g_member, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to accept a group membership request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval        = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$user_id       = bp_loggedin_user_id();\n\t\t$group_request = $this->fetch_single_membership_request( $request->get_param( 'request_id' ) );\n\n\t\tif ( ! $user_id ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to make an update.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( ! $group_request ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_membership_requests_invalid_id',\n\t\t\t\t__( 'Invalid group membership request ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || groups_is_user_admin( $user_id, $group_request->item_id ) ) {\n\t\t\t$retval = true;\n\t\t} else {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_member_request_cannot_update_item',\n\t\t\t\t__( 'User is not allowed to approve membership requests to this group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the group membership request `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request can continue.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Reject a pending group membership request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get invite.\n\t\t$group_request = $this->fetch_single_membership_request( $request->get_param( 'request_id' ) );\n\n\t\t// Set the invite response before it is deleted.\n\t\t$previous = $this->prepare_item_for_response( $group_request, $request );\n\n\t\t/**\n\t\t * If this change is being initiated by the requesting user,\n\t\t * use the `delete` function.\n\t\t */\n\t\tif ( bp_loggedin_user_id() === $group_request->user_id ) {\n\t\t\t$success = groups_delete_membership_request( false, $group_request->user_id, $group_request->item_id );\n\t\t\t/**\n\t\t\t * Otherwise, this change is being initiated by a group admin or site admin,\n\t\t\t * and we should use the `reject` function.\n\t\t\t */\n\t\t} else {\n\t\t\t$success = groups_reject_membership_request( false, $group_request->user_id, $group_request->item_id );\n\t\t}\n\n\t\tif ( ! $success ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_membership_requests_cannot_delete_item',\n\t\t\t\t__( 'There was an error rejecting the membership request.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t$user  = bp_rest_get_user( $group_request->user_id );\n\t\t$group = $this->groups_endpoint->get_group_object( $group_request->item_id );\n\n\t\t/**\n\t\t * Fires after a group membership request is rejected via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_User          $user     The user.\n\t\t * @param BP_Groups_Group  $group    The group object.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_group_membership_requests_delete_item', $user, $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to reject a group membership request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval        = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$user_id       = bp_loggedin_user_id();\n\t\t$group_request = $this->fetch_single_membership_request( $request->get_param( 'request_id' ) );\n\n\t\tif ( ! $user_id ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to delete a request.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( ! $group_request ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_membership_requests_invalid_id',\n\t\t\t\t__( 'Invalid group membership request ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || $user_id === $group_request->user_id || groups_is_user_admin( $user_id, $group_request->item_id ) ) {\n\t\t\t$retval = true;\n\t\t} else {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_membership_requests_cannot_delete_item',\n\t\t\t\t__( 'User is not allowed to delete this membership request.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the group membership request `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the request may proceed.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares group invitation data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Invitation   $invite  Invite object.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $invite, $request ) {\n\t\t$data = array(\n\t\t\t'id'            => $invite->id,\n\t\t\t'user_id'       => $invite->user_id,\n\t\t\t'invite_sent'   => $invite->invite_sent,\n\t\t\t'inviter_id'    => $invite->inviter_id,\n\t\t\t'group_id'      => $invite->item_id,\n\t\t\t'date_modified' => bp_rest_prepare_date_response( $invite->date_modified ),\n\t\t\t'type'          => $invite->type,\n\t\t\t'message'       => array(\n\t\t\t\t'raw'      => $invite->content,\n\t\t\t\t'rendered' => apply_filters( 'the_content', $invite->content ),\n\t\t\t),\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t$response->add_links( $this->prepare_links( $invite ) );\n\n\t\t/**\n\t\t * Filter a group invite value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  Request used to generate the response.\n\t\t * @param BP_Invitation    $invite   The invite object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_prepare_value', $response, $request, $invite );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Invitation $invite Invite object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $invite ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\t\t$url  = $base . $invite->id;\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $url ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t\t'user'       => array(\n\t\t\t\t'href'       => bp_rest_get_object_url( $invite->user_id, 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t),\n\t\t);\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array         $links  The prepared links of the REST response.\n\t\t * @param BP_Invitation $invite Invite object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_prepare_links', $links, $invite );\n\t}\n\n\t/**\n\t * Helper function to fetch a single group invite.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $request_id The ID of the request you wish to fetch.\n\t * @return BP_Invitation|bool $group_request Membership request if found, false otherwise.\n\t */\n\tpublic function fetch_single_membership_request( $request_id = 0 ) {\n\t\t$group_requests = groups_get_requests( array( 'id' => $request_id ) );\n\t\tif ( $group_requests ) {\n\t\t\treturn current( $group_requests );\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Endpoint args.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\n\t\t\t$args['message']['type']        = 'string';\n\t\t\t$args['message']['description'] = __( 'The optional message to send to the invited user.', 'buddypress' );\n\t\t\t$args['message']['default']     = '';\n\t\t\t$args['group_id']['required']   = true;\n\t\t\t$args['user_id']['default']     = bp_loggedin_user_id();\n\n\t\t\t// Remove arguments not needed for the CREATABLE transport method.\n\t\t\tunset( $args['message']['properties'], $args['date_modified'], $args['type'] );\n\n\t\t} elseif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key = 'update_item';\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_group_membership_requests_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the group membership request schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\n\t\t\t// Get schema from the membership endpoint.\n\t\t\t$schema = $this->invites_endpoint->get_item_schema();\n\n\t\t\t// Set title to this endpoint.\n\t\t\t$schema['title'] = 'bp_group_membership_request';\n\n\t\t\t// Adapt some item schema property descriptions to this endpoint.\n\t\t\t$schema['properties']['user_id']['description']  = __( 'The ID of the user who requested a Group membership.', 'buddypress' );\n\t\t\t$schema['properties']['group_id']['description'] = __( 'The ID of the group the user requested a membership for.', 'buddypress' );\n\t\t\t$schema['properties']['type']['default']         = 'request';\n\n\t\t\t// Remove unused properties.\n\t\t\tunset( $schema['properties']['invite_sent'], $schema['properties']['inviter_id'] );\n\n\t\t\t// Cache current schema here.\n\t\t\t$this->schema = $schema;\n\t\t}\n\n\t\t/**\n\t\t * Filters the group membership request schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections of group invites.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = $this->invites_endpoint->get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t// Adapt some item schema property descriptions to this endpoint.\n\t\t$params['user_id']['description']  = __( 'Return only Membership requests made by a specific user.', 'buddypress' );\n\t\t$params['group_id']['description'] = __( 'The ID of the group the user requested a membership for.', 'buddypress' );\n\n\t\t// Remove unused properties.\n\t\tunset( $params['invite_sent'], $params['inviter_id'] );\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_membership_requests_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-groups/classes/class-bp-rest-groups-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Groups_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Groups endpoints.\n *\n * @since 0.1.0\n */\nclass BP_REST_Groups_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Groups_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = buddypress()->groups->id;\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context'         => $this->get_context_param( array( 'default' => 'view' ) ),\n\t\t\t\t\t\t'populate_extras' => array(\n\t\t\t\t\t\t\t'description'       => __( 'Whether to fetch extra BP data about the returned group.', 'buddypress' ),\n\t\t\t\t\t\t\t'context'           => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t'default'           => false,\n\t\t\t\t\t\t\t'type'              => 'boolean',\n\t\t\t\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/me',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'max' => array(\n\t\t\t\t\t\t'description' => __( 'The maximum amount of groups the user is member of to return. Defaults to all groups.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'default'     => 0,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_current_user_groups' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_current_user_groups_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'view' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve groups.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Request List of groups object data.\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'type'         => $request->get_param( 'type' ),\n\t\t\t'order'        => $request->get_param( 'order' ),\n\t\t\t'fields'       => $request->get_param( 'fields' ),\n\t\t\t'orderby'      => $request->get_param( 'orderby' ),\n\t\t\t'user_id'      => $request->get_param( 'user_id' ),\n\t\t\t'include'      => $request->get_param( 'include' ),\n\t\t\t'parent_id'    => $request->get_param( 'parent_id' ),\n\t\t\t'exclude'      => $request->get_param( 'exclude' ),\n\t\t\t'search_terms' => $request->get_param( 'search' ),\n\t\t\t'meta_query'   => $request->get_param( 'meta' ), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query\n\t\t\t'group_type'   => $request->get_param( 'group_type' ),\n\t\t\t'show_hidden'  => $request->get_param( 'show_hidden' ),\n\t\t\t'status'       => $request->get_param( 'status' ),\n\t\t\t'per_page'     => $request->get_param( 'per_page' ),\n\t\t\t'page'         => $request->get_param( 'page' ),\n\t\t);\n\n\t\tif ( empty( $request->get_param( 'parent_id' ) ) ) {\n\t\t\t$args['parent_id'] = null;\n\t\t}\n\n\t\t// See if the user can see hidden groups.\n\t\tif ( ! empty( $request->get_param( 'show_hidden' ) ) && true === (bool) $request->get_param( 'show_hidden' ) && ! $this->can_see_hidden_groups( $request ) ) {\n\t\t\t$args['show_hidden'] = false;\n\t\t}\n\n\t\tif ( true === $request->get_param( 'populate_extras' ) ) {\n\t\t\t$args['update_meta_cache'] = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_groups_get_items_query_args', $args, $request );\n\n\t\t// Actually, query it.\n\t\t$groups = groups_get_groups( $args );\n\n\t\t// Users need (at least, should we be more restrictive ?) to be logged in to use the edit context.\n\t\tif ( 'edit' === $request->get_param( 'context' ) && ! is_user_logged_in() ) {\n\t\t\t$request->set_param( 'context', 'view' );\n\t\t}\n\n\t\t$retval = array();\n\t\tforeach ( $groups['groups'] as $group ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $groups['total'], $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a list of groups is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $groups   Fetched groups.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_groups_get_items', $groups, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to group items.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the groups `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the user has access to groups component items.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_item( $request ) {\n\t\t$group = $this->get_group_object( $request );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Groups_Group  $group    Fetched group.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_groups_get_item', $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get information about a specific group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you cannot view the group.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'groups' ) ) ) {\n\t\t\t$group = $this->get_group_object( $request );\n\n\t\t\tif ( empty( $group->id ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( $this->can_see( $group ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the groups `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Create a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// If no group name.\n\t\tif ( empty( $request->get_param( 'name' ) ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_create_group_empty_name',\n\t\t\t\t__( 'Please, enter the name of group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 400,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$group_id = groups_create_group( $this->prepare_item_for_database( $request ) );\n\n\t\tif ( ! is_numeric( $group_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_create_group',\n\t\t\t\t__( 'Cannot create new group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$group         = $this->get_group_object( $group_id );\n\t\t$fields_update = $this->update_additional_fields_for_object( $group, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t// Set group type(s).\n\t\tif ( ! empty( $request->get_param( 'types' ) ) ) {\n\t\t\tbp_groups_set_group_type( $group_id, $request->get_param( 'types' ) );\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group is created via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Groups_Group  $group    The created group.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_groups_create_item', $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to create a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to create groups.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\t$current_user_id = (int) bp_loggedin_user_id();\n\t\t$creator_id      = (int) $request->get_param( 'creator_id' );\n\n\t\tif ( ( $current_user_id && $current_user_id === $creator_id && bp_user_can_create_groups() ) || bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the groups `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$group_id = groups_create_group( $this->prepare_item_for_database( $request ) );\n\n\t\tif ( ! is_numeric( $group_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_group',\n\t\t\t\t__( 'Cannot update existing group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$group         = $this->get_group_object( $group_id );\n\t\t$fields_update = $this->update_additional_fields_for_object( $group, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a group is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Groups_Group  $group    The updated group.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_groups_update_item', $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to update this group.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$group  = $this->get_group_object( $request );\n\n\t\tif ( empty( $group->id ) ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to update this group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( $this->can_user_delete_or_update( $group ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the groups `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the group before it's deleted.\n\t\t$group    = $this->get_group_object( $request );\n\t\t$previous = $this->prepare_item_for_response( $group, $request );\n\n\t\tif ( ! groups_delete_group( $group->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_cannot_delete',\n\t\t\t\t__( 'Could not delete the group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a group is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param object           $group    The deleted group.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_groups_delete_item', $group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to delete this group.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$group  = $this->get_group_object( $request );\n\n\t\tif ( empty( $group->id ) ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_group_invalid_id',\n\t\t\t\t__( 'Invalid group ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to delete this group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} elseif ( $this->can_user_delete_or_update( $group ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the groups `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieves the current user groups.\n\t *\n\t * @since 7.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.\n\t */\n\tpublic function get_current_user_groups( $request ) {\n\t\t$current_user_id = get_current_user_id();\n\t\t$max             = $request->get_param( 'max' );\n\n\t\tif ( empty( $current_user_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_group_invalid_user_id',\n\t\t\t\t__( 'Invalid user ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$per_page = -1;\n\t\tif ( $max ) {\n\t\t\t$per_page = (int) $max;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 7.0.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters(\n\t\t\t'bp_rest_groups_get_current_user_groups_query_args',\n\t\t\tarray(\n\t\t\t\t'user_id'            => $current_user_id,\n\t\t\t\t'per_page'           => $per_page,\n\t\t\t\t'page'               => 1,\n\t\t\t\t'show_hidden'        => true,\n\t\t\t\t'update_admin_cache' => false,\n\t\t\t\t'update_meta_cache'  => false,\n\t\t\t),\n\t\t\t$request\n\t\t);\n\n\t\t// Actually, query it.\n\t\t$groups = groups_get_groups( $args );\n\n\t\t$retval = array();\n\t\tforeach ( $groups['groups'] as $group ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $group, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after the user's list of groups is fetched via the REST API.\n\t\t *\n\t\t * @since 7.0.0\n\t\t *\n\t\t * @param array            $groups   Fetched groups.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_groups_get_current_user_groups', $groups, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to fetch the user's groups.\n\t *\n\t * @since 7.0.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_current_user_groups_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you need to be logged in to view your groups.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the groups `get_current_user_groups` permissions check.\n\t\t *\n\t\t * @since 7.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_get_current_user_groups_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares group data for return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Groups_Group $item     The group object.\n\t * @param WP_REST_Request $request  Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $item, $request ) {\n\t\t$data = array(\n\t\t\t'id'                 => $item->id,\n\t\t\t'creator_id'         => bp_get_group_creator_id( $item ),\n\t\t\t'parent_id'          => $item->parent_id,\n\t\t\t'date_created'       => bp_rest_prepare_date_response( $item->date_created, get_date_from_gmt( $item->date_created ) ),\n\t\t\t'date_created_gmt'   => bp_rest_prepare_date_response( $item->date_created ),\n\t\t\t'created_since'      => bp_core_time_since( $item->date_created ),\n\t\t\t'description'        => array(\n\t\t\t\t'raw'      => $item->description,\n\t\t\t\t'rendered' => bp_get_group_description( $item ),\n\t\t\t),\n\t\t\t'enable_forum'       => bp_group_is_forum_enabled( $item ),\n\t\t\t'link'               => bp_get_group_url( $item ),\n\t\t\t'name'               => bp_get_group_name( $item ),\n\t\t\t'slug'               => bp_get_group_slug( $item ),\n\t\t\t'status'             => bp_get_group_status( $item ),\n\t\t\t'types'              => bp_groups_get_group_type( $item->id, false ),\n\t\t\t'admins'             => array(),\n\t\t\t'mods'               => array(),\n\t\t\t'total_member_count' => 0,\n\t\t\t'last_activity'      => null,\n\t\t\t'last_activity_diff' => null,\n\t\t);\n\n\t\t// Return avatars, if allowed.\n\t\tif ( true !== bp_disable_group_avatar_uploads() ) {\n\t\t\t$data['avatar_urls'] = array(\n\t\t\t\t'full'  => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t\t'object'  => 'group',\n\t\t\t\t\t\t'item_id' => $item->id,\n\t\t\t\t\t\t'type'    => 'full',\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t\t'thumb' => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t\t'object'  => 'group',\n\t\t\t\t\t\t'item_id' => $item->id,\n\t\t\t\t\t\t'type'    => 'thumb',\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Get group type(s).\n\t\tif ( false === $data['types'] ) {\n\t\t\t$data['types'] = array();\n\t\t}\n\n\t\t$context = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\n\t\t// If this is the 'edit' context or 'populate_extras' has been requested.\n\t\tif ( 'edit' === $context || true === $request->get_param( 'populate_extras' ) ) {\n\t\t\t$data['total_member_count'] = (int) $item->total_member_count;\n\t\t\t$data['last_activity']      = bp_rest_prepare_date_response( $item->last_activity, get_date_from_gmt( $item->last_activity ) );\n\t\t\t$data['last_activity_gmt']  = bp_rest_prepare_date_response( $item->last_activity );\n\t\t\t$data['last_activity_diff'] = bp_get_group_last_active( $item );\n\t\t}\n\n\t\t// If this is the 'edit' context, get more data about the group.\n\t\tif ( 'edit' === $context ) {\n\t\t\t// Add admins and moderators to their respective arrays.\n\t\t\t$admin_mods = groups_get_group_members(\n\t\t\t\tarray(\n\t\t\t\t\t'group_id'   => $item->id,\n\t\t\t\t\t'group_role' => array(\n\t\t\t\t\t\t'admin',\n\t\t\t\t\t\t'mod',\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tforeach ( (array) $admin_mods['members'] as $user ) {\n\t\t\t\t// Make sure to unset private data.\n\t\t\t\t$private_keys = array_intersect(\n\t\t\t\t\tarray_keys( get_object_vars( $user ) ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'user_pass',\n\t\t\t\t\t\t'user_email',\n\t\t\t\t\t\t'user_activation_key',\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\tforeach ( $private_keys as $private_key ) {\n\t\t\t\t\tunset( $user->{$private_key} );\n\t\t\t\t}\n\n\t\t\t\tif ( ! empty( $user->is_admin ) ) {\n\t\t\t\t\t$data['admins'][] = $user;\n\t\t\t\t} else {\n\t\t\t\t\t$data['mods'][] = $user;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $item ) );\n\n\t\t/**\n\t\t * Filter a group value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  Request used to generate the response.\n\t\t * @param BP_Groups_Group  $item     The group object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_prepare_value', $response, $request, $item );\n\t}\n\n\t/**\n\t * Prepare a group for create or update.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return stdClass|WP_Error\n\t */\n\tprotected function prepare_item_for_database( $request ) {\n\t\t$schema = $this->get_item_schema();\n\t\t$group  = $this->get_group_object( $request );\n\n\t\tif ( isset( $group->id ) && $group->id ) {\n\t\t\t$prepared_group = $group;\n\t\t} else {\n\t\t\t$prepared_group = new stdClass();\n\t\t}\n\n\t\t// Group ID.\n\t\tif ( ! empty( $group->id ) ) {\n\t\t\t$prepared_group->group_id = $group->id;\n\t\t}\n\n\t\t// Group Creator ID.\n\t\tif ( ! empty( $schema['properties']['creator_id'] ) && ! empty( $request->get_param( 'creator_id' ) ) ) {\n\t\t\t$prepared_group->creator_id = (int) $request->get_param( 'creator_id' );\n\n\t\t\t// Fallback on the current user otherwise.\n\t\t} else {\n\t\t\t$prepared_group->creator_id = bp_loggedin_user_id();\n\t\t}\n\n\t\t// Group Slug.\n\t\tif ( ! empty( $schema['properties']['slug'] ) && ! empty( $request->get_param( 'slug' ) ) ) {\n\t\t\t$prepared_group->slug = $request->get_param( 'slug' );\n\t\t}\n\n\t\t// Group Name.\n\t\tif ( ! empty( $schema['properties']['name'] ) && ! empty( $request->get_param( 'name' ) ) ) {\n\t\t\t$prepared_group->name = $request->get_param( 'name' );\n\t\t}\n\n\t\t// Do additional checks for the Group's slug.\n\t\tif ( WP_REST_Server::CREATABLE === $request->get_method() || ( isset( $group->slug ) && isset( $prepared_group->slug ) && $group->slug !== $prepared_group->slug ) ) {\n\t\t\t// Fallback on the group name if the slug is not defined.\n\t\t\tif ( ! isset( $prepared_group->slug ) && ! isset( $group->slug ) ) {\n\t\t\t\t$prepared_group->slug = $prepared_group->name;\n\t\t\t}\n\n\t\t\t// Make sure it is unique and sanitize it.\n\t\t\t$prepared_group->slug = groups_check_slug( sanitize_title( esc_attr( $prepared_group->slug ) ) );\n\t\t}\n\n\t\t// Group description.\n\t\tif ( ! empty( $schema['properties']['description'] ) && ! empty( $request->get_param( 'description' ) ) ) {\n\t\t\tif ( is_string( $request->get_param( 'description' ) ) ) {\n\t\t\t\t$prepared_group->description = $request->get_param( 'description' );\n\t\t\t} elseif ( isset( $request['description']['raw'] ) ) {\n\t\t\t\t$prepared_group->description = $request['description']['raw'];\n\t\t\t}\n\t\t}\n\n\t\t// Group status.\n\t\tif ( ! empty( $schema['properties']['status'] ) && ! empty( $request->get_param( 'status' ) ) ) {\n\t\t\t$prepared_group->status = $request->get_param( 'status' );\n\t\t}\n\n\t\t// Group Forum Enabled.\n\t\tif ( ! empty( $schema['properties']['enable_forum'] ) && ! empty( $request->get_param( 'enable_forum' ) ) ) {\n\t\t\t$prepared_group->enable_forum = (bool) $request->get_param( 'enable_forum' );\n\t\t}\n\n\t\t// Group Parent ID.\n\t\tif ( ! empty( $schema['properties']['parent_id'] ) && ! empty( $request->get_param( 'parent_id' ) ) ) {\n\t\t\t$prepared_group->parent_id = $request->get_param( 'parent_id' );\n\t\t}\n\n\t\t// Update group type(s).\n\t\tif ( isset( $prepared_group->group_id ) && ! empty( $request->get_param( 'types' ) ) ) {\n\t\t\tbp_groups_set_group_type( $prepared_group->group_id, $request->get_param( 'types' ), false );\n\t\t}\n\n\t\t// Remove group type(s).\n\t\tif ( isset( $prepared_group->group_id ) && ! empty( $request->get_param( 'remove_types' ) ) ) {\n\t\t\tarray_map(\n\t\t\t\tfunction ( $type ) use ( $prepared_group ) {\n\t\t\t\t\tbp_groups_remove_group_type( $prepared_group->group_id, $type );\n\t\t\t\t},\n\t\t\t\t$request->get_param( 'remove_types' )\n\t\t\t);\n\t\t}\n\n\t\t// Append group type(s).\n\t\tif ( isset( $prepared_group->group_id ) && ! empty( $request->get_param( 'append_types' ) ) ) {\n\t\t\tbp_groups_set_group_type( $prepared_group->group_id, $request->get_param( 'append_types' ), true );\n\t\t}\n\n\t\t/**\n\t\t * Filters a group before it is inserted or updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param stdClass        $prepared_group An object prepared for inserting or updating the database.\n\t\t * @param WP_REST_Request $request        Request object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_pre_insert_value', $prepared_group, $request );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Groups_Group $group Group object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $group ) {\n\t\t$base  = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $group->id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\t// Embed group creator if available.\n\t\tif ( ! empty( $group->creator_id ) ) {\n\t\t\t$links['user'] = array(\n\t\t\t\t'href'       => bp_rest_get_object_url( $group->creator_id, 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t);\n\t\t}\n\n\t\t// Embed parent group if available.\n\t\tif ( ! empty( $group->parent ) ) {\n\t\t\t$links['parent'] = array(\n\t\t\t\t'href'       => rest_url( $base . $group->parent ),\n\t\t\t\t'embeddable' => true,\n\t\t\t);\n\t\t}\n\n\t\t// Actions.\n\n\t\t$user_id = bp_loggedin_user_id();\n\n\t\tif ( is_user_logged_in() && false === bp_group_is_user_banned( $group->id, $user_id ) ) {\n\t\t\t$membership_namespace = \"{$this->rest_base}/membership-requests\";\n\t\t\t$request_id           = groups_check_for_membership_request( $user_id, $group->id );\n\t\t\t$is_group_member      = wp_validate_boolean( $group->is_member );\n\n\t\t\tswitch ( true ) {\n\t\t\t\t// The logged in user is not a member of a private group, action to: request a membership.\n\t\t\t\tcase 'private' === $group->status && false === $is_group_member:\n\t\t\t\t\t$links['bp-action-group-membership-request-membership'] = array(\n\t\t\t\t\t\t'href'     => rest_url( sprintf( '/%1$s/%2$s/', $this->namespace, $membership_namespace ) ),\n\t\t\t\t\t\t'group_id' => $group->id,\n\t\t\t\t\t\t'user_id'  => $user_id,\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\t// The logged in user already requested a membership to the group, action to: withdraw the request.\n\t\t\t\tcase is_numeric( $request_id ):\n\t\t\t\t\t$links['bp-action-group-membership-withdraw-request'] = array(\n\t\t\t\t\t\t'href' => bp_rest_get_object_url( $request_id, $membership_namespace ),\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\t// The logged in user is a member of the group, action to: leave.\n\t\t\t\tcase true === $is_group_member:\n\t\t\t\t\t$links['bp-action-group-leave'] = array(\n\t\t\t\t\t\t'href' => bp_rest_get_object_url( $user_id, \"{$this->rest_base}/{$group->id}/members\" ),\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\t// The logged in user is not a member of a public group, action to: join.\n\t\t\t\tcase 'public' === $group->status && false === $is_group_member:\n\t\t\t\t\t$links['bp-action-group-join'] = array(\n\t\t\t\t\t\t'href'     => rest_url( sprintf( '/%1$s/%2$s/', $this->namespace, \"{$this->rest_base}/{$group->id}/members\" ) ),\n\t\t\t\t\t\t'group_id' => $group->id,\n\t\t\t\t\t\t'user_id'  => $user_id,\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\t// The logged in user is invited to join the group, actions to: accept and reject invite.\n\t\t\t\tcase true === $group->is_invited:\n\t\t\t\t\t$invites_class = new BP_Groups_Invitation_Manager();\n\t\t\t\t\t$ids           = $invites_class->get_invitations(\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'user_id' => $user_id,\n\t\t\t\t\t\t\t'item_id' => $group->id,\n\t\t\t\t\t\t\t'fields'  => 'ids',\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\n\t\t\t\t\t$invite_action = array( 'href' => bp_rest_get_object_url( $ids[0], \"{$this->rest_base}/{$group->id}/invites\" ) );\n\n\t\t\t\t\t$links['bp-action-group-accept-invite'] = $invite_action;\n\t\t\t\t\t$links['bp-action-group-reject-invite'] = $invite_action;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $links The prepared links of the REST response.\n\t\t * @param BP_Groups_Group $group Group object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_prepare_links', $links, $group );\n\t}\n\n\t/**\n\t * See if user can delete or update a group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  BP_Groups_Group $group Group item.\n\t * @return bool\n\t */\n\tprotected function can_user_delete_or_update( $group ) {\n\t\treturn ( bp_current_user_can( 'bp_moderate' ) || groups_is_user_admin( bp_loggedin_user_id(), $group->id ) );\n\t}\n\n\t/**\n\t * Can a user see a group?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  BP_Groups_Group $group Group object.\n\t * @return bool\n\t */\n\tpublic function can_see( $group ) {\n\t\t// If it is not a hidden group, user can see it.\n\t\tif ( 'hidden' !== $group->status ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check for moderators or if user is a member of the group.\n\t\treturn ( bp_current_user_can( 'bp_moderate' ) || groups_is_user_member( bp_loggedin_user_id(), $group->id ) );\n\t}\n\n\t/**\n\t * Can this user see hidden groups?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return bool\n\t */\n\tprotected function can_see_hidden_groups( $request ) {\n\t\tif ( bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn (\n\t\t\tis_user_logged_in()\n\t\t\t&& ! empty( $request->get_param( 'user_id' ) )\n\t\t\t&& absint( $request->get_param( 'user_id' ) ) === bp_loggedin_user_id()\n\t\t);\n\t}\n\n\t/**\n\t * Get group object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  int|WP_REST_Request $request Full details about the request or an group integer.\n\t * @return false|BP_Groups_Group\n\t */\n\tpublic function get_group_object( $request ) {\n\t\tif ( $request instanceof WP_REST_Request ) {\n\t\t\tif ( ! empty( $request->get_param( 'group_id' ) ) ) {\n\t\t\t\t$group_id = (int) $request->get_param( 'group_id' );\n\t\t\t} else {\n\t\t\t\t$group_id = (int) $request->get_param( 'id' );\n\t\t\t}\n\t\t} elseif ( is_numeric( $request ) ) {\n\t\t\t$group_id = (int) $request;\n\t\t}\n\n\t\t$group = groups_get_group( $group_id );\n\n\t\tif ( empty( $group ) || empty( $group->id ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn $group;\n\t}\n\n\t/**\n\t * Edit some arguments for the endpoint's CREATABLE and EDITABLE methods.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key                         = 'create_item';\n\t\t\t$args['description']['type'] = 'string';\n\n\t\t\t// Add group types.\n\t\t\t$args['types'] = array(\n\t\t\t\t'description'       => __( 'Assign one or more type to a group. To assign more than one type, use a comma separated list of types.', 'buddypress' ),\n\t\t\t\t'type'              => 'string',\n\t\t\t\t'enum'              => bp_groups_get_group_types(),\n\t\t\t\t'sanitize_callback' => 'bp_rest_sanitize_group_types',\n\t\t\t\t'validate_callback' => 'bp_rest_validate_group_types',\n\t\t\t);\n\n\t\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t\t$key = 'update_item';\n\t\t\t\tunset( $args['slug'] );\n\n\t\t\t\t// Append group types.\n\t\t\t\t$args['append_types'] = array(\n\t\t\t\t\t'description'       => __( 'Append one or more type to a group. To append more than one type, use a comma separated list of types.', 'buddypress' ),\n\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t'enum'              => bp_groups_get_group_types(),\n\t\t\t\t\t'sanitize_callback' => 'bp_rest_sanitize_group_types',\n\t\t\t\t\t'validate_callback' => 'bp_rest_validate_group_types',\n\t\t\t\t);\n\n\t\t\t\t// Remove group types.\n\t\t\t\t$args['remove_types'] = array(\n\t\t\t\t\t'description'       => __( 'Remove one or more type of a group. To remove more than one type, use a comma separated list of types.', 'buddypress' ),\n\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t'enum'              => bp_groups_get_group_types(),\n\t\t\t\t\t'sanitize_callback' => 'bp_rest_sanitize_group_types',\n\t\t\t\t\t'validate_callback' => 'bp_rest_validate_group_types',\n\t\t\t\t);\n\t\t\t}\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_groups_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the group schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_groups',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                 => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'creator_id'         => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the user who created the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'default'     => bp_loggedin_user_id(),\n\t\t\t\t\t),\n\t\t\t\t\t'name'               => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The name of the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'slug'               => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The URL-friendly slug for the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'link'               => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The permalink to the Group on the site.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'description'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The description of the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t\t'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the description of the Group, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the description of the Group, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'status'             => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The status of the Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => buddypress()->groups->valid_status,\n\t\t\t\t\t\t'default'     => 'public',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'enable_forum'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Whether the Group has a forum enabled or not.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t\t'parent_id'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'ID of the parent Group.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'date_created'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The date the Group was created, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_created_gmt'   => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the Group was created, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'created_since'      => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Time elapsed since the Group was created, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'default'     => '',\n\t\t\t\t\t),\n\t\t\t\t\t'types'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The type(s) of the Group.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'enum'        => bp_groups_get_group_types(),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'string',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'admins'             => array(\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Group administrators.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'object',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'mods'               => array(\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Group moderators.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'object',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'total_member_count' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Count of all Group members.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'last_activity'      => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The date the Group was last active, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'last_activity_gmt'  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the Group was last active, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'last_activity_diff' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'The human diff time the Group was last active, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tif ( true !== bp_disable_group_avatar_uploads() ) {\n\t\t\t\t$avatar_properties = array();\n\n\t\t\t\t$avatar_properties['full'] = array(\n\t\t\t\t\t/* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t);\n\n\t\t\t\t$avatar_properties['thumb'] = array(\n\t\t\t\t\t/* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t);\n\n\t\t\t\t$schema['properties']['avatar_urls'] = array(\n\t\t\t\t\t'description' => __( 'Avatar URLs for the group.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t'properties'  => $avatar_properties,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Cache current schema here.\n\t\t\t$this->schema = $schema;\n\t\t}\n\n\t\t/**\n\t\t * Filters the group schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_group_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections of groups.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t$params['type'] = array(\n\t\t\t'description'       => __( 'Shorthand for certain orderby/order combinations.', 'buddypress' ),\n\t\t\t'default'           => 'active',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'active', 'newest', 'alphabetical', 'random', 'popular' ),\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['order'] = array(\n\t\t\t'description'       => __( 'Order sort attribute ascending or descending.', 'buddypress' ),\n\t\t\t'default'           => 'desc',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'asc', 'desc' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['orderby'] = array(\n\t\t\t'description'       => __( 'Order Groups by which attribute.', 'buddypress' ),\n\t\t\t'default'           => 'date_created',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'date_created', 'last_activity', 'total_member_count', 'name', 'random' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['status'] = array(\n\t\t\t'description'       => __( 'Group statuses to limit results to.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array(\n\t\t\t\t'enum' => buddypress()->groups->valid_status,\n\t\t\t\t'type' => 'string',\n\t\t\t),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_string_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Pass a user ID to limit to only Groups that this user is a member of.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['parent_id'] = array(\n\t\t\t'description'       => __( 'Get Groups that are children of the specified Group(s) IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t// @todo Confirm what's the proper sanitization here.\n\t\t$params['meta'] = array(\n\t\t\t'description'       => __( 'Get Groups based on their meta data information.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'string' ),\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['include'] = array(\n\t\t\t'description'       => __( 'Ensure result set includes Groups with specific IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes Groups with specific IDs', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['group_type'] = array(\n\t\t\t'description'       => __( 'Limit results set to a certain Group type.', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => bp_groups_get_group_types(),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_group_types',\n\t\t\t'validate_callback' => 'bp_rest_validate_group_types',\n\t\t);\n\n\t\t$params['enable_forum'] = array(\n\t\t\t'description'       => __( 'Whether the Group has a forum enabled or not.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['show_hidden'] = array(\n\t\t\t'description'       => __( 'Whether results should include hidden Groups.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['populate_extras'] = array(\n\t\t\t'description'       => __( 'Whether to fetch extra BP data about the returned groups.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_groups_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-members/classes/class-bp-rest-attachments-member-avatar-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Attachments_Member_Avatar_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Member Avatar endpoints.\n *\n * @since 0.1.0\n */\nclass BP_REST_Attachments_Member_Avatar_Endpoint extends WP_REST_Controller {\n\tuse BP_REST_Attachments;\n\n\t/**\n\t * BP_Attachment_Avatar Instance.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_Attachment_Avatar\n\t */\n\tprotected $avatar_instance;\n\n\t/**\n\t * Member object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var WP_User\n\t */\n\tprotected $user;\n\n\t/**\n\t * Member object type.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var string\n\t */\n\tprotected $object = 'user';\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Members_Avatar_REST_Controller' );\n\n\t\t$this->namespace       = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base       = 'members';\n\t\t$this->avatar_instance = new BP_Attachment_Avatar();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<user_id>[\\d]+)/avatar',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'user_id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_item_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Fetch an existing member avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$args = array();\n\n\t\tforeach ( array( 'full', 'thumb' ) as $type ) {\n\t\t\t$args[ $type ] = bp_core_fetch_avatar(\n\t\t\t\tarray(\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t\t'type'    => $type,\n\t\t\t\t\t'item_id' => (int) $this->user->ID,\n\t\t\t\t\t'html'    => (bool) $request->get_param( 'html' ),\n\t\t\t\t\t'alt'     => $request->get_param( 'alt' ),\n\t\t\t\t\t'no_grav' => (bool) $request->get_param( 'no_gravatar' ),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get the avatar object.\n\t\t$avatar = $this->get_avatar_object( $args );\n\n\t\tif ( ! $avatar->full && ! $avatar->thumb ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_avatar_no_image',\n\t\t\t\t__( 'Sorry, there was a problem fetching the avatar.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $avatar, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a member avatar is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param string            $avatar   The avatar.\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_member_avatar_get_item', $avatar, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to get a member avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'members' ) ) ) {\n\t\t\t$retval     = new WP_Error(\n\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t\t$this->user = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\n\t\t\tif ( $this->user instanceof WP_User ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the member avatar `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_avatar_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Upload a member avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the image file from  $_FILES.\n\t\t$files = $request->get_file_params();\n\n\t\tif ( empty( $files ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_avatar_no_image_file',\n\t\t\t\t__( 'Sorry, you need an image file to upload.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Upload the avatar.\n\t\t$avatar = $this->upload_avatar_from_file( $files );\n\t\tif ( is_wp_error( $avatar ) ) {\n\t\t\treturn $avatar;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $avatar, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a member avatar is uploaded via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param stdClass          $avatar   Avatar object.\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_member_avatar_create_item', $avatar, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to upload a member avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\tif ( ! is_wp_error( $retval ) ) {\n\t\t\t$args  = array();\n\t\t\t$error = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tif ( ! isset( $this->user->ID ) || ! isset( $this->object ) ) {\n\t\t\t\t$retval = $error;\n\t\t\t} else {\n\t\t\t\t$args = array(\n\t\t\t\t\t'item_id' => $this->user->ID,\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t);\n\n\t\t\t\tif ( ! is_user_logged_in() ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t\t__( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( 'POST' === $request->get_method() && bp_disable_avatar_uploads() ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_attachments_member_avatar_disabled',\n\t\t\t\t\t\t__( 'Sorry, member avatar upload is disabled.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => 500,\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_attachments_current_user_can( 'edit_avatar', $args ) ) {\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = $error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the member avatar `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_avatar_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete an existing member avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$user_id = (int) $this->user->ID;\n\n\t\tif ( ! bp_get_user_has_avatar( $user_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_avatar_no_uploaded_avatar',\n\t\t\t\t__( 'Sorry, there are no uploaded avatars for this user on this site.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$args = array();\n\n\t\tforeach ( array( 'full', 'thumb' ) as $type ) {\n\t\t\t$args[ $type ] = bp_core_fetch_avatar(\n\t\t\t\tarray(\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t\t'type'    => $type,\n\t\t\t\t\t'item_id' => $user_id,\n\t\t\t\t\t'html'    => false,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get the avatar object before deleting it.\n\t\t$avatar = $this->get_avatar_object( $args );\n\n\t\t$deleted = bp_core_delete_existing_avatar(\n\t\t\tarray(\n\t\t\t\t'object'  => $this->object,\n\t\t\t\t'item_id' => $user_id,\n\t\t\t)\n\t\t);\n\n\t\tif ( ! $deleted ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_avatar_delete_failed',\n\t\t\t\t__( 'Sorry, there was a problem deleting the avatar.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $avatar,\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a member avatar is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_member_avatar_delete_item', $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to delete member avatar.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->create_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the member avatar `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_avatar_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares avatar data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param object          $avatar  Avatar object.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $avatar, $request ) {\n\t\t$data = array(\n\t\t\t'full'  => $avatar->full,\n\t\t\t'thumb' => $avatar->thumb,\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t/**\n\t\t * Filter a member avatar value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response  $response Response.\n\t\t * @param WP_REST_Request   $request  Request used to generate the response.\n\t\t * @param object            $avatar   Avatar object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_avatar_prepare_value', $response, $request, $avatar );\n\t}\n\n\t/**\n\t * Get the member avatar schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_attachments_member_avatar',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'full'  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Full size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'thumb' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Thumb size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the attachments member avatar schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_avatar_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for the `get_item`.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t// Removing unused params.\n\t\tunset( $params['search'], $params['page'], $params['per_page'] );\n\n\t\t$params['html'] = array(\n\t\t\t'description'       => __( 'Whether to return an <img> HTML element, vs a raw URL to an avatar.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['alt'] = array(\n\t\t\t'description'       => __( 'The alt attribute for the <img> element.', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['no_gravatar'] = array(\n\t\t\t'description'       => __( 'Whether to disable the default Gravatar fallback.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the item collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_avatar_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-members/classes/class-bp-rest-attachments-member-cover-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Attachments_Member_Cover_Endpoint class\n *\n * @package BuddyPress\n * @since 6.0.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Member Cover endpoints.\n *\n * /members/<user_id>/cover\n *\n * @since 6.0.0\n */\nclass BP_REST_Attachments_Member_Cover_Endpoint extends WP_REST_Controller {\n\tuse BP_REST_Attachments;\n\n\t/**\n\t * BP_Attachment_Cover_Image Instance.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var BP_Attachment_Cover_Image\n\t */\n\tprotected $attachment_instance;\n\n\t/**\n\t * Member object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var WP_User\n\t */\n\tprotected $user;\n\n\t/**\n\t * Member object type.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @var string\n\t */\n\tprotected $object = 'user';\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Members_Cover_REST_Controller' );\n\n\t\t$this->namespace           = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base           = 'members';\n\t\t$this->attachment_instance = new BP_Attachment_Cover_Image();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<user_id>[\\d]+)/cover',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'user_id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the User.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Fetch an existing user cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$cover_url = bp_attachments_get_attachment(\n\t\t\t'url',\n\t\t\tarray(\n\t\t\t\t'item_id' => $this->user->ID,\n\t\t\t)\n\t\t);\n\n\t\tif ( empty( $cover_url ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_cover_no_image',\n\t\t\t\t__( 'Sorry, there was a problem fetching this user cover.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $cover_url, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a user cover is fetched via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param string            $cover_url  The user cover url.\n\t\t * @param WP_REST_Response  $response   The response data.\n\t\t * @param WP_REST_Request   $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_member_cover_get_item', $cover_url, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to get a user cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'members' ) ) ) {\n\t\t\t$retval     = new WP_Error(\n\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t\t$this->user = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\n\t\t\tif ( $this->user instanceof WP_User ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the user cover `get_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_cover_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Upload a user cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the image file from $_FILES.\n\t\t$files = $request->get_file_params();\n\n\t\tif ( empty( $files ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_cover_no_image_file',\n\t\t\t\t__( 'Sorry, you need an image file to upload.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Upload the user cover.\n\t\t$cover_url = $this->upload_cover_from_file( $files );\n\t\tif ( is_wp_error( $cover_url ) ) {\n\t\t\treturn $cover_url;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $cover_url, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a user cover is uploaded via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param string            $cover_url  The user cover url.\n\t\t * @param WP_REST_Response  $response   The response data.\n\t\t * @param WP_REST_Request   $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_member_cover_create_item', $cover_url, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to upload a user cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = $this->delete_item_permissions_check( $request );\n\n\t\tif ( true === $retval && bp_disable_cover_image_uploads() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_cover_disabled',\n\t\t\t\t__( 'Sorry, user cover upload is disabled.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the user cover `create_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_cover_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete an existing user cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$cover_url = bp_attachments_get_attachment(\n\t\t\t'url',\n\t\t\tarray(\n\t\t\t\t'item_id' => $this->user->ID,\n\t\t\t)\n\t\t);\n\n\t\t$deleted = bp_attachments_delete_file(\n\t\t\tarray(\n\t\t\t\t'item_id' => (int) $this->user->ID,\n\t\t\t)\n\t\t);\n\n\t\tif ( ! $deleted ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_attachments_member_cover_delete_failed',\n\t\t\t\t__( 'Sorry, there was a problem deleting this user cover.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $cover_url,\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a user cover is deleted via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param WP_User           $user      The user object.\n\t\t * @param WP_REST_Response  $response  The response data.\n\t\t * @param WP_REST_Request   $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_attachments_member_cover_delete_item', $this->user, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to delete a user cover.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\tif ( ! is_wp_error( $retval ) ) {\n\t\t\t$args  = array();\n\t\t\t$error = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tif ( ! isset( $this->user->ID ) || ! isset( $this->object ) ) {\n\t\t\t\t$retval = $error;\n\t\t\t} else {\n\t\t\t\t$args = array(\n\t\t\t\t\t'item_id' => $this->user->ID,\n\t\t\t\t\t'object'  => $this->object,\n\t\t\t\t);\n\n\t\t\t\tif ( ! is_user_logged_in() ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t\t__( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} elseif ( bp_attachments_current_user_can( 'edit_cover_image', $args ) ) {\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = $error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the user cover `delete_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_cover_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares user cover to return as an object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param string          $cover_url User cover url.\n\t * @param WP_REST_Request $request   Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $cover_url, $request ) {\n\t\t$data = array(\n\t\t\t'image' => $cover_url,\n\t\t);\n\n\t\t$context = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data    = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data    = $this->filter_response_by_context( $data, $context );\n\n\t\t$response = rest_ensure_response( $data );\n\n\t\t/**\n\t\t * Filter a user cover value returned from the API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param WP_REST_Response  $response  Response.\n\t\t * @param WP_REST_Request   $request   Request used to generate the response.\n\t\t * @param string            $cover_url Group cover url.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_cover_prepare_value', $response, $request, $cover_url );\n\t}\n\n\t/**\n\t * Get the plugin schema, conforming to JSON Schema.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_attachments_member_cover',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'image' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Full size of the image file.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the attachment member cover schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_attachments_member_cover_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-members/classes/class-bp-rest-members-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Members_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * BuddyPress Members endpoints.\n *\n * /members/\n * /members/{id}\n *\n * @since 0.1.0\n */\nclass BP_REST_Members_Endpoint extends WP_REST_Users_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Members_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = 'members';\n\t}\n\n\t/**\n\t * Registers the routes for the objects of the controller.\n\t *\n\t * @since 7.0.0\n\t *\n\t * @see register_rest_route()\n\t */\n\tpublic function register_routes() {\n\t\tparent::register_routes();\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'Unique identifier for the member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context'         => parent::get_context_param( array( 'default' => 'view' ) ),\n\t\t\t\t\t\t'populate_extras' => array(\n\t\t\t\t\t\t\t'description'       => __( 'Whether to fetch extra BP data about the returned member.', 'buddypress' ),\n\t\t\t\t\t\t\t'context'           => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t'default'           => false,\n\t\t\t\t\t\t\t'type'              => 'boolean',\n\t\t\t\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'force'    => array(\n\t\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t\t\t'default'     => false,\n\t\t\t\t\t\t\t'description' => __( 'Required to be true, as members do not support trashing.', 'buddypress' ),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'reassign' => array(\n\t\t\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t\t\t'description'       => __( 'Reassign the deleted member\\'s posts and links to this user ID.', 'buddypress' ),\n\t\t\t\t\t\t\t'required'          => true,\n\t\t\t\t\t\t\t'sanitize_callback' => array( $this, 'check_reassign' ),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_public_item_schema' ),\n\t\t\t),\n\t\t\ttrue // Override the members/id READABLE route generated by WP_REST_Users_Controller.\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve users.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'type'            => $request->get_param( 'type' ),\n\t\t\t'user_id'         => $request->get_param( 'user_id' ),\n\t\t\t'user_ids'        => $request->get_param( 'user_ids' ),\n\t\t\t'xprofile_query'  => $request->get_param( 'xprofile' ),\n\t\t\t'include'         => $request->get_param( 'include' ),\n\t\t\t'exclude'         => $request->get_param( 'exclude' ),\n\t\t\t'populate_extras' => $request->get_param( 'populate_extras' ),\n\t\t\t'member_type'     => $request->get_param( 'member_type' ),\n\t\t\t'search_terms'    => $request->get_param( 'search' ),\n\t\t\t'per_page'        => $request->get_param( 'per_page' ),\n\t\t\t'page'            => $request->get_param( 'page' ),\n\t\t);\n\n\t\tif ( empty( $request->get_param( 'user_ids' ) ) ) {\n\t\t\t$args['user_ids'] = false;\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'exclude' ) ) ) {\n\t\t\t$args['exclude'] = false;\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'include' ) ) ) {\n\t\t\t$args['include'] = false;\n\t\t}\n\n\t\tif ( isset( $args['xprofile_query']['args'] ) && is_array( $args['xprofile_query']['args'] ) ) {\n\t\t\t$xprofile_query_args = $args['xprofile_query']['args'];\n\n\t\t\tif ( isset( $args['xprofile_query']['relation'] ) ) {\n\t\t\t\t$xprofile_query_args = array_merge(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'relation' => $args['xprofile_query']['relation'],\n\t\t\t\t\t),\n\t\t\t\t\t$xprofile_query_args\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t$args['xprofile_query'] = $xprofile_query_args;\n\t\t} else {\n\t\t\t$args['xprofile_query'] = false;\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'member_type' ) ) ) {\n\t\t\t$args['member_type'] = '';\n\t\t}\n\n\t\tif ( is_null( $args['search_terms'] ) ) {\n\t\t\t$args['search_terms'] = false;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_members_get_items_query_args', $args, $request );\n\n\t\t// Actually, query it.\n\t\t$member_query = new BP_User_Query( $args );\n\t\t$members      = array_values( $member_query->results );\n\n\t\t$retval = array();\n\t\tforeach ( $members as $member ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $member, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $member_query->total_users, $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a list of members is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $members  Fetched members.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_members_get_items', $members, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to get all users.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'members' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the members `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the user has access to members component items.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieves a single member.\n\t *\n\t * @since 7.0.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.\n\t */\n\tpublic function get_item( $request ) {\n\t\tif ( true === $request->get_param( 'populate_extras' ) ) {\n\t\t\t$args = array(\n\t\t\t\t'user_ids'        => array( $request->get_param( 'id' ) ),\n\t\t\t\t'populate_extras' => true,\n\t\t\t);\n\n\t\t\t// Get the member with BuddyPress extra data.\n\t\t\t$member_query = new BP_User_Query( $args );\n\t\t\t$member       = reset( $member_query->results );\n\n\t\t\t$member   = $this->prepare_item_for_response( $member, $request );\n\t\t\t$response = rest_ensure_response( $member );\n\n\t\t\treturn $response;\n\t\t}\n\n\t\treturn parent::get_item( $request );\n\t}\n\n\t/**\n\t * Checks if a given request has access to read a user.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'members' ) ) ) {\n\t\t\t$user = bp_rest_get_user( $request->get_param( 'id' ) );\n\n\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( 'edit' === $request->get_param( 'context' ) ) {\n\t\t\t\tif ( get_current_user_id() === $user->ID || bp_current_user_can( 'list_users' ) ) {\n\t\t\t\t\t$retval = true;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t\t__( 'Sorry, you are not allowed to view members with the edit context.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the members `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Checks if a given request has access create members.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = parent::create_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter or override the members `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Check if a given request has access to update a member.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$error  = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$retval = $error;\n\n\t\t$user             = bp_rest_get_user( $request->get_param( 'id' ) );\n\t\t$member_type_edit = ! empty( $request->get_param( 'member_type' ) );\n\n\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\t$action = 'delete';\n\n\t\t\tif ( 'DELETE' !== $request->get_method() ) {\n\t\t\t\t$action = 'update';\n\t\t\t}\n\n\t\t\tif ( get_current_user_id() === $user->ID ) {\n\t\t\t\tif ( $member_type_edit && ! bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t\t\t$retval = $error;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = parent::update_item_permissions_check( $request );\n\t\t\t\t}\n\t\t\t} elseif ( ! $this->can_manage_member( $user, $action ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you are not allowed to view members.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the members `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a member.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->update_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the members `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Checks if a given request has access to delete the current user.\n\t *\n\t * @since 0.1.0\n\t * @since 0.7.0 Do implement this method.\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.\n\t */\n\tpublic function delete_current_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed delete your account.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( ! bp_disable_account_deletion() ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the members `delete_current_item` permissions check.\n\t\t *\n\t\t * @since 0.7.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_delete_current_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Deletes the current user.\n\t *\n\t * @since 0.1.0\n\t * @since 0.7.0 Do implement this method.\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.\n\t */\n\tpublic function delete_current_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$user = bp_rest_get_user( get_current_user_id() );\n\n\t\tif ( ! $user instanceof WP_User ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$previous = $this->prepare_item_for_response( $user, $request );\n\t\t$result   = bp_core_delete_account();\n\n\t\tif ( ! $result ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_members_cannot_delete',\n\t\t\t\t__( 'Your account cannot be deleted.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 500 )\n\t\t\t);\n\t\t}\n\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/* this action is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */\n\t\tdo_action( 'rest_delete_user', $user, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Prepares a single user output for response.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_User         $user    User object.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $user, $request ) {\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->user_data( $user, $context, $request );\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t$response->add_links( $this->prepare_links( $user, $data ) );\n\n\t\t// Update current user's last activity.\n\t\tif ( strpos( $request->get_route(), 'members/me' ) !== false && get_current_user_id() === $user->ID ) {\n\t\t\tbp_update_user_last_activity();\n\t\t}\n\n\t\t/**\n\t\t * Filters user data returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response $response The response object.\n\t\t * @param WP_REST_Request  $request  The request object.\n\t\t * @param WP_User          $user     WP_User object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_prepare_value', $response, $request, $user );\n\t}\n\n\t/**\n\t * Prepares links for the user request.\n\t *\n\t * @since 11.0.0\n\t *\n\t * @param WP_User $user      User object.\n\t * @param array   $user_data User data.\n\t * @return array\n\t */\n\tprotected function prepare_links( $user, $user_data = array() ) {\n\t\t$base  = sprintf( '/%1$s/%2$s/', $this->namespace, $this->rest_base );\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $user->ID ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\t// Actions.\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\tif ( bp_is_active( 'friends' ) ) {\n\t\t\t\t$friends_component = buddypress()->friends->id;\n\t\t\t\t$friends_action    = array( 'href' => bp_rest_get_object_url( $user->ID, $friends_component ) );\n\n\t\t\t\tswitch ( $user_data['friendship_status_slug'] ) {\n\t\t\t\t\tcase 'not_friends':\n\t\t\t\t\t\t$links['bp-action-add-friendship'] = array(\n\t\t\t\t\t\t\t'href'         => rest_url( sprintf( '/%1$s/%2$s/', $this->namespace, $friends_component ) ),\n\t\t\t\t\t\t\t'initiator_id' => bp_loggedin_user_id(),\n\t\t\t\t\t\t\t'friend_id'    => $user->ID,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'is_friend':\n\t\t\t\t\t\t$links['bp-action-delete-friendship'] = $friends_action;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'pending':\n\t\t\t\t\t\t$links['bp-action-cancel-friendship-request'] = $friends_action;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'awaiting_response':\n\t\t\t\t\t\t$links['bp-action-accept-friendship-request'] = $friends_action;\n\t\t\t\t\t\t$links['bp-action-reject-friendship-request'] = $friends_action;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tbp_is_active( 'messages' )\n\t\t\t\t&& (\n\t\t\t\t\ttrue === wp_validate_boolean( $user_data['friendship_status'] )\n\t\t\t\t\t|| buddypress()->messages->autocomplete_all === true\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\t$links['bp-action-create-thread'] = array(\n\t\t\t\t\t'href'    => rest_url( sprintf( '/%1$s/%2$s/', $this->namespace, buddypress()->messages->id ) ),\n\t\t\t\t\t'user_id' => $user->ID,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 11.0.0\n\t\t *\n\t\t * @param array   $links The prepared links of the REST response.\n\t\t * @param WP_User $user  The User object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_member_prepare_links', $links, $user );\n\t}\n\n\t/**\n\t * Method to facilitate fetching of user data.\n\t *\n\t * This was abstracted to be used in other BuddyPress endpoints.\n\t *\n\t * @since 0.1.0\n\t * @since 7.0.0 Add the `$request` parameter.\n\t *\n\t * @param WP_User         $user    User object.\n\t * @param string          $context The context of the request. Defaults to 'view'.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return array\n\t */\n\tpublic function user_data( $user, $context, $request ) {\n\t\tif ( ! $context ) {\n\t\t\t$context = 'view';\n\t\t}\n\n\t\t$data = array(\n\t\t\t'id'                     => (int) $user->ID,\n\t\t\t'name'                   => $user->display_name,\n\t\t\t'user_login'             => $user->user_login,\n\t\t\t'roles'                  => array(),\n\t\t\t'capabilities'           => array(),\n\t\t\t'extra_capabilities'     => array(),\n\t\t\t'registered_date'        => null,\n\t\t\t'registered_date_gmt'    => null,\n\t\t\t'friendship_status'      => false,\n\t\t\t'friendship_status_slug' => '',\n\t\t);\n\n\t\t// Get fields to output for REST endpoint.\n\t\t$fields = $request->get_param( '_fields' );\n\n\t\t// If comma-delimited, explode into array.\n\t\tif ( ! empty( $fields ) && ! is_array( $fields ) ) {\n\t\t\t$fields = explode( ',', $fields );\n\t\t}\n\n\t\t$fields = array_flip( (array) $fields );\n\n\t\t// Link.\n\t\tif ( empty( $fields ) || ! empty( $fields['link'] ) ) {\n\t\t\t$data['link'] = bp_members_get_user_url( $user->ID );\n\t\t}\n\n\t\t// Member types.\n\t\tif ( empty( $fields ) || ! empty( $fields['member_types'] ) ) {\n\t\t\t$data['member_types'] = bp_get_member_type( $user->ID, false );\n\t\t}\n\n\t\t// Xprofile data.\n\t\tif ( empty( $fields ) || ! empty( $fields['xprofile'] ) ) {\n\t\t\t$data['xprofile'] = $this->xprofile_data( $user->ID );\n\t\t}\n\n\t\t// Populate extras.\n\t\tif ( $request->get_param( 'populate_extras' ) ) {\n\t\t\t$data['registered_since'] = bp_core_time_since( $user->user_registered );\n\t\t\t$data['last_activity']    = array(\n\t\t\t\t'timediff' => null,\n\t\t\t\t'date'     => null,\n\t\t\t\t'date_gmt' => null,\n\t\t\t);\n\n\t\t\tif ( get_current_user_id() === $user->ID ) {\n\t\t\t\t$right_now                         = gmdate( 'Y-m-d H:i:s', bp_core_current_time( true, 'timestamp' ) );\n\t\t\t\t$data['last_activity']['timediff'] = bp_core_time_since( $right_now );\n\t\t\t\t$data['last_activity']['date']     = bp_rest_prepare_date_response( $right_now, get_date_from_gmt( $right_now ) );\n\t\t\t\t$data['last_activity']['date_gmt'] = bp_rest_prepare_date_response( $right_now );\n\n\t\t\t} elseif ( $user->last_activity ) {\n\t\t\t\t$data['last_activity']['timediff'] = bp_core_time_since( $user->last_activity );\n\t\t\t\t$data['last_activity']['date']     = bp_rest_prepare_date_response( $user->last_activity, get_date_from_gmt( $user->last_activity ) );\n\t\t\t\t$data['last_activity']['date_gmt'] = bp_rest_prepare_date_response( $user->last_activity );\n\t\t\t}\n\n\t\t\tif ( bp_is_active( 'activity' ) ) {\n\t\t\t\t$data['latest_update'] = array(\n\t\t\t\t\t'id'       => 0,\n\t\t\t\t\t'raw'      => '',\n\t\t\t\t\t'rendered' => '',\n\t\t\t\t);\n\n\t\t\t\tif ( isset( $user->latest_update ) && $user->latest_update ) {\n\t\t\t\t\t$activity_data = maybe_unserialize( $user->latest_update );\n\n\t\t\t\t\tif ( isset( $activity_data['id'], $activity_data['content'] ) ) {\n\t\t\t\t\t\t$data['latest_update']['id']       = $activity_data['id'];\n\t\t\t\t\t\t$data['latest_update']['raw']      = $activity_data['content'];\n\t\t\t\t\t\t$data['latest_update']['rendered'] = apply_filters( 'bp_get_activity_content', $activity_data['content'] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( bp_is_active( 'friends' ) && isset( $user->total_friend_count ) && $user->total_friend_count ) {\n\t\t\t\t$data['total_friend_count'] = absint( $user->total_friend_count );\n\t\t\t}\n\t\t}\n\n\t\t// Friends related fields.\n\t\tif ( bp_is_active( 'friends' ) && get_current_user_id() !== $user->ID ) {\n\t\t\tif ( empty( $fields ) ||\n\t\t\t\t( ! empty( $fields['friendship_status_slug'] ) || ! empty( $fields['friendship_status'] ) )\n\t\t\t) {\n\t\t\t\t$friendship_status = friends_check_friendship_status( get_current_user_id(), $user->ID );\n\n\t\t\t\t$data['friendship_status_slug'] = $friendship_status;\n\t\t\t\t$data['friendship_status']      = ( 'is_friend' === $friendship_status );\n\t\t\t}\n\t\t}\n\n\t\tif ( 'edit' === $context && current_user_can( 'list_users' ) ) {\n\t\t\tif ( isset( $user->data ) ) {\n\t\t\t\t$data['registered_date']     = bp_rest_prepare_date_response( $user->data->user_registered, get_date_from_gmt( $user->data->user_registered ) );\n\t\t\t\t$data['registered_date_gmt'] = bp_rest_prepare_date_response( $user->data->user_registered );\n\t\t\t}\n\n\t\t\t$data['roles']              = isset( $user->roles ) ? array_values( (array) $user->roles ) : array();\n\t\t\t$data['capabilities']       = isset( $user->allcaps ) ? array_keys( (array) $user->allcaps ) : array();\n\t\t\t$data['extra_capabilities'] = isset( $user->caps ) ? array_keys( (array) $user->caps ) : array();\n\t\t}\n\n\t\t// The name used for that user in @-mentions.\n\t\tif ( bp_is_active( 'activity' ) &&\n\t\t\t( empty( $fields ) || ! empty( $fields['mention_name'] ) )\n\t\t) {\n\t\t\t$data['mention_name'] = bp_activity_get_user_mentionname( $user->ID );\n\t\t}\n\n\t\t// Avatars.\n\t\tif ( true === buddypress()->avatar->show_avatars &&\n\t\t\t( empty( $fields ) || ! empty( $fields['avatar_urls'] ) )\n\t\t) {\n\t\t\t$data['avatar_urls'] = array(\n\t\t\t\t'full'  => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'item_id' => $user->ID,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t\t'type'    => 'full',\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t\t'thumb' => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'item_id' => $user->ID,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t\t'type'    => 'thumb',\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Fallback.\n\t\tif ( false === $data['member_types'] ) {\n\t\t\t$data['member_types'] = array();\n\t\t}\n\n\t\treturn $data;\n\t}\n\n\t/**\n\t * Prepares a single user for creation or update.\n\t *\n\t * @todo Improve sanitization and schema verification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Request object.\n\t * @return stdClass\n\t */\n\tprotected function prepare_item_for_database( $request ) {\n\t\t$prepared_user = parent::prepare_item_for_database( $request );\n\n\t\t// The parent class uses username instead of user_login.\n\t\tif ( ! isset( $prepared_user->user_login ) && ! empty( $request->get_param( 'user_login' ) ) ) {\n\t\t\t$prepared_user->user_login = $request->get_param( 'user_login' );\n\t\t}\n\n\t\t/**\n\t\t * Until BP REST version 0.3.0 the `types` parameter was used into the schema\n\t\t * but not used to actually assign the member type to the user.\n\t\t */\n\t\t$types = $request->get_param( 'types' );\n\t\tif ( $types ) {\n\t\t\t$request->set_param( 'member_type', bp_rest_sanitize_member_types( $types ) );\n\t\t}\n\n\t\t// Set member type.\n\t\tif ( isset( $prepared_user->ID ) && ! empty( $request->get_param( 'member_type' ) ) ) {\n\n\t\t\t// Append on update. Add on creation.\n\t\t\t$append = WP_REST_Server::EDITABLE === $request->get_method();\n\n\t\t\tbp_set_member_type( $prepared_user->ID, $request->get_param( 'member_type' ), $append );\n\t\t}\n\n\t\t/**\n\t\t * Filters an user object before it is inserted or updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param stdClass        $prepared_user An object prepared for inserting or updating the database.\n\t\t * @param WP_REST_Request $request       Request object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_pre_insert_value', $prepared_user, $request );\n\t}\n\n\t/**\n\t * Get XProfile info from the user.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  int $user_id User ID.\n\t * @return array\n\t */\n\tprotected function xprofile_data( $user_id ) {\n\t\t$data = array();\n\n\t\t// Get XProfile groups, only if the component is active.\n\t\tif ( bp_is_active( 'xprofile' ) ) {\n\t\t\t$fields_endpoint = new BP_REST_XProfile_Fields_Endpoint();\n\n\t\t\t$groups = bp_xprofile_get_groups(\n\t\t\t\tarray(\n\t\t\t\t\t'user_id'          => $user_id,\n\t\t\t\t\t'fetch_fields'     => true,\n\t\t\t\t\t'fetch_field_data' => true,\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tforeach ( $groups as $group_order => $group ) {\n\t\t\t\t$data['groups'][ $group_order ] = array(\n\t\t\t\t\t'name' => $group->name,\n\t\t\t\t\t'id'   => $group->id,\n\t\t\t\t);\n\n\t\t\t\tforeach ( $group->fields as $item ) {\n\t\t\t\t\t$data['groups'][ $group_order ]['fields'][ $item->field_order ] = array(\n\t\t\t\t\t\t'name'  => $item->name,\n\t\t\t\t\t\t'id'    => $item->id,\n\t\t\t\t\t\t'value' => array(\n\t\t\t\t\t\t\t'raw'          => $item->data->value,\n\t\t\t\t\t\t\t'unserialized' => $fields_endpoint->get_profile_field_unserialized_value( $item->data->value ),\n\t\t\t\t\t\t\t'rendered'     => $fields_endpoint->get_profile_field_rendered_value( $item->data->value, $item ),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t$data = array( __( 'No extended profile data available as the component is inactive', 'buddypress' ) );\n\t\t}\n\n\t\treturn $data;\n\t}\n\n\t/**\n\t * Can user manage (delete/update) a member?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_User $user User object.\n\t * @param  string  $action The action to perform (update or delete).\n\t * @return bool\n\t */\n\tprotected function can_manage_member( $user, $action = 'delete' ) {\n\t\t$capability = 'delete_user';\n\n\t\tif ( 'update' === $action ) {\n\t\t\t$capability = 'edit_user';\n\t\t}\n\n\t\treturn current_user_can( $capability, $user->ID );\n\t}\n\n\t/**\n\t * Updates the values of additional fields added to a data object.\n\t *\n\t * This function makes sure updating the field value thanks to the `id` property of\n\t * the created/updated object type is consistent accross BuddyPress components.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_User         $user    The WordPress user object.\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return bool|WP_Error True on success, WP_Error object if a field cannot be updated.\n\t */\n\tprotected function update_additional_fields_for_object( $user, $request ) {\n\t\tif ( ! isset( $user->data ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'invalid_user',\n\t\t\t\t__( 'The data for the user was not found.', 'buddypress' )\n\t\t\t);\n\t\t}\n\n\t\t$member     = $user->data;\n\t\t$member->id = $member->ID;\n\n\t\treturn parent::update_additional_fields_for_object( $member, $request );\n\t}\n\n\t/**\n\t * Make sure to retrieve the needed arguments for the endpoint CREATABLE method.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\t// Add member type args.\n\t\t$member_type_args = array(\n\t\t\t'description'       => __( 'Assign a member type to a member, use a comma separated list of member types to assign more than one.', 'buddypress' ),\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => bp_get_member_types(),\n\t\t\t'context'           => array( 'edit' ),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_member_types',\n\t\t\t'validate_callback' => 'bp_rest_sanitize_member_types',\n\t\t);\n\n\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\n\t\t\t// We don't need the mention name to create a user.\n\t\t\tunset( $args['mention_name'] );\n\n\t\t\t// Add member type args.\n\t\t\t$args['member_type'] = $member_type_args;\n\n\t\t\t// But we absolutely need the email.\n\t\t\t$args['email'] = array(\n\t\t\t\t'description' => __( 'The email address for the member.', 'buddypress' ),\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'format'      => 'email',\n\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t'required'    => true,\n\t\t\t);\n\t\t} elseif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key = 'update_item';\n\n\t\t\t/**\n\t\t\t * 1. The mention name or user login are not updatable.\n\t\t\t * 2. The password belongs to the Settings endpoint parameter.\n\t\t\t */\n\t\t\tunset( $args['mention_name'], $args['user_login'], $args['password'] );\n\n\t\t\t// Add member type args.\n\t\t\t$args['member_type'] = $member_type_args;\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_members_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the members schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_members',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                     => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'name'                   => array(\n\t\t\t\t\t\t'description' => __( 'Display name for the member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'mention_name'           => array(\n\t\t\t\t\t\t'description' => __( 'The name used for that user in @-mentions.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'link'                   => array(\n\t\t\t\t\t\t'description' => __( 'Profile URL of the member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'user_login'             => array(\n\t\t\t\t\t\t'description' => __( 'An alphanumeric identifier for the Member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => array( $this, 'check_username' ),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'member_types'           => array(\n\t\t\t\t\t\t'description' => __( 'Member types associated with the member.', 'buddypress' ),\n\t\t\t\t\t\t'enum'        => bp_get_member_types(),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'string',\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'registered_date'        => array(\n\t\t\t\t\t\t'description' => __( 'Registration date for the member, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'registered_date_gmt'    => array(\n\t\t\t\t\t\t'description' => __( 'Registration date for the member, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'registered_since'       => array(\n\t\t\t\t\t\t'description' => __( 'Elapsed time since the member registered.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'password'               => array(\n\t\t\t\t\t\t'description' => __( 'Password for the member (never included).', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'context'     => array(), // Password is never displayed.\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => array( $this, 'check_user_password' ),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'roles'                  => array(\n\t\t\t\t\t\t'description' => __( 'Roles assigned to the member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'string',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'capabilities'           => array(\n\t\t\t\t\t\t'description' => __( 'All capabilities assigned to the user.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'extra_capabilities'     => array(\n\t\t\t\t\t\t'description' => __( 'Any extra capabilities assigned to the user.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'xprofile'               => array(\n\t\t\t\t\t\t'description' => __( 'Member XProfile groups and its fields.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'friendship_status'      => array(\n\t\t\t\t\t\t'description' => __( 'Friendship relation with, current, logged in user.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'bool',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'friendship_status_slug' => array(\n\t\t\t\t\t\t'description' => __( 'Slug of the friendship status with current logged in user.', 'buddypress' ),\n\t\t\t\t\t\t'enum'        => array( 'is_friend', 'not_friends', 'pending', 'awaiting_response' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'last_activity'          => array(\n\t\t\t\t\t\t'description' => __( 'Last date the member was active on the site.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'timediff' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'English-language representation of the date.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'date'     => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Date in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'date_gmt' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Date as GMT.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'latest_update'          => array(\n\t\t\t\t\t\t'description' => __( 'The content of the latest activity posted by the member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'id'       => array(\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the activity.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the activity, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the activity, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'total_friend_count'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit', 'embed' ),\n\t\t\t\t\t\t'description' => __( 'Total number of friends for the member.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tif ( true === buddypress()->avatar->show_avatars ) {\n\t\t\t\t$avatar_properties = array();\n\n\t\t\t\t$avatar_properties['full'] = array(\n\t\t\t\t\t/* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t);\n\n\t\t\t\t$avatar_properties['thumb'] = array(\n\t\t\t\t\t/* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */\n\t\t\t\t\t'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'format'      => 'uri',\n\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t);\n\n\t\t\t\t$schema['properties']['avatar_urls'] = array(\n\t\t\t\t\t'description' => __( 'Avatar URLs for the member.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t'properties'  => $avatar_properties,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Cache current schema here.\n\t\t\t$this->schema = $schema;\n\t\t}\n\n\t\t/**\n\t\t * Filters the members schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params = array_intersect_key(\n\t\t\tparent::get_collection_params(),\n\t\t\tarray(\n\t\t\t\t'context'  => true,\n\t\t\t\t'page'     => true,\n\t\t\t\t'per_page' => true,\n\t\t\t\t'search'   => true,\n\t\t\t)\n\t\t);\n\n\t\t$params['type'] = array(\n\t\t\t'description'       => __( 'Shorthand for certain orderby/order combinations.', 'buddypress' ),\n\t\t\t'default'           => 'newest',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'active', 'newest', 'alphabetical', 'random', 'online', 'popular' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Limit results to friends of a user.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_ids'] = array(\n\t\t\t'description'       => __( 'Pass IDs of users to limit result set.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['include'] = array(\n\t\t\t'description'       => __( 'Ensure result set includes specific IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes specific IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['populate_extras'] = array(\n\t\t\t'description'       => __( 'Whether to fetch extra BP data about the returned members.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['member_type'] = array(\n\t\t\t'description'       => __( 'Limit results set to certain type(s).', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'string' ),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_string_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['xprofile'] = array(\n\t\t\t'description'       => __( 'Limit results set to a certain XProfile field.', 'buddypress' ),\n\t\t\t'type'              => array( 'array', 'object' ),\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_members_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-members/classes/class-bp-rest-signup-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Signup_Endpoint class\n *\n * @package BuddyPress\n * @since 6.0.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Signup endpoints.\n *\n * Use /signup\n * Use /signup/{id}\n * Use /signup/resend\n * Use /signup/activate/{activation_key}\n *\n * @since 6.0.0\n */\nclass BP_REST_Signup_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Members_Signup_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = 'signup';\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 6.0.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\w-]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description'       => __( 'Identifier for the signup. Can be a signup ID, an email address, or an activation key.', 'buddypress' ),\n\t\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'view' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'edit' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\t// Register the activate route.\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/activate/(?P<activation_key>[\\w-]+)',\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'activate_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'activate_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'edit' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\t// Register the resend route.\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/resend',\n\t\t\tarray(\n\t\t\t\t'args' => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description'       => __( 'Identifier for the signup. Can be a signup ID, an email address, or an activation key.', 'buddypress' ),\n\t\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t'required'          => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'signup_resend_activation_email' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'signup_resend_activation_email_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param( array( 'default' => 'edit' ) ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve signups.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'include'    => $request->get_param( 'include' ),\n\t\t\t'order'      => $request->get_param( 'order' ),\n\t\t\t'orderby'    => $request->get_param( 'orderby' ),\n\t\t\t'user_login' => $request->get_param( 'user_login' ),\n\t\t\t'number'     => $request->get_param( 'number' ),\n\t\t\t'offset'     => $request->get_param( 'offset' ),\n\t\t);\n\n\t\tif ( empty( $request->get_param( 'include' ) ) ) {\n\t\t\t$args['include'] = false;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_signup_get_items_query_args', $args, $request );\n\n\t\t// Actually, query it.\n\t\t$signups = BP_Signup::get( $args );\n\n\t\t$retval = array();\n\t\tforeach ( $signups['signups'] as $signup ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $signup, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $signups['total'], $args['number'] );\n\n\t\t/**\n\t\t * Fires after a list of signups is fetched via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array            $signups   Fetched signups.\n\t\t * @param WP_REST_Response $response  The response data.\n\t\t * @param WP_REST_Request  $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_signup_get_items', $signups, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to signup items.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),\n\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t);\n\n\t\t$capability = is_multisite() ? 'manage_network_users' : 'edit_users';\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),\n\t\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t\t);\n\t\t} elseif ( bp_current_user_can( $capability ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the signup `get_items` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve single signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t// Get signup.\n\t\t$signup = $this->get_signup_object( $request->get_param( 'id' ) );\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $signup, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires before a signup is retrieved via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Signup         $signup    The signup object.\n\t\t * @param WP_REST_Response  $response  The response data.\n\t\t * @param WP_REST_Request   $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_signup_get_item', $signup, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get a signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),\n\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t);\n\n\t\t$capability = is_multisite() ? 'manage_network_users' : 'edit_users';\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),\n\t\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t\t);\n\t\t} elseif ( bp_current_user_can( $capability ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\tif ( ! is_wp_error( $retval ) ) {\n\t\t\t$signup = $this->get_signup_object( $request->get_param( 'id' ) );\n\n\t\t\tif ( empty( $signup ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Invalid signup id.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the signup `get_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Create signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Validate user signup.\n\t\t$signup_validation = bp_core_validate_user_signup( $request->get_param( 'user_login' ), $request->get_param( 'user_email' ) );\n\t\tif ( is_wp_error( $signup_validation['errors'] ) && $signup_validation['errors']->get_error_messages() ) {\n\t\t\t// Return the first error.\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_signup_validation_failed',\n\t\t\t\t$signup_validation['errors']->get_error_message(),\n\t\t\t\tarray( 'status' => 500 )\n\t\t\t);\n\t\t}\n\n\t\t// Use the validated login and email.\n\t\t$user_login = $signup_validation['user_name'];\n\t\t$user_email = $signup_validation['user_email'];\n\n\t\t// Init the signup meta.\n\t\t$meta = array();\n\n\t\t// Init some Multisite specific variables.\n\t\t$domain     = '';\n\t\t$path       = '';\n\t\t$site_title = '';\n\t\t$site_name  = '';\n\n\t\tif ( is_multisite() ) {\n\t\t\t$user_login    = preg_replace( '/\\s+/', '', sanitize_user( $user_login, true ) );\n\t\t\t$user_email    = sanitize_email( $user_email );\n\t\t\t$wp_key_suffix = $user_email;\n\n\t\t\tif ( $this->is_blog_signup_allowed() ) {\n\t\t\t\t$site_title = $request->get_param( 'site_title' );\n\t\t\t\t$site_name  = $request->get_param( 'site_name' );\n\n\t\t\t\tif ( $site_title && $site_name ) {\n\t\t\t\t\t// Validate the blog signup.\n\t\t\t\t\t$blog_signup_validation = bp_core_validate_blog_signup( $site_name, $site_title );\n\t\t\t\t\tif ( is_wp_error( $blog_signup_validation['errors'] ) && $blog_signup_validation['errors']->get_error_messages() ) {\n\t\t\t\t\t\t// Return the first error.\n\t\t\t\t\t\treturn new WP_Error(\n\t\t\t\t\t\t\t'bp_rest_blog_signup_validation_failed',\n\t\t\t\t\t\t\t$blog_signup_validation['errors']->get_error_message(),\n\t\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t\t'status' => 500,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t$domain        = $blog_signup_validation['domain'];\n\t\t\t\t\t$wp_key_suffix = $domain;\n\t\t\t\t\t$path          = $blog_signup_validation['path'];\n\t\t\t\t\t$site_title    = $blog_signup_validation['blog_title'];\n\t\t\t\t\t$site_public   = (bool) $request->get_param( 'site_public' );\n\n\t\t\t\t\t$meta = array(\n\t\t\t\t\t\t'lang_id' => 1,\n\t\t\t\t\t\t'public'  => $site_public ? 1 : 0,\n\t\t\t\t\t);\n\n\t\t\t\t\t$site_language = $request->get_param( 'site_language' );\n\t\t\t\t\t$languages     = $this->get_available_languages();\n\n\t\t\t\t\tif ( in_array( $site_language, $languages, true ) ) {\n\t\t\t\t\t\t$language = wp_unslash( sanitize_text_field( $site_language ) );\n\n\t\t\t\t\t\tif ( $language ) {\n\t\t\t\t\t\t\t$meta['WPLANG'] = $language;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$password       = $request->get_param( 'password' );\n\t\t$check_password = $this->check_user_password( $password );\n\n\t\tif ( is_wp_error( $check_password ) ) {\n\t\t\treturn $check_password;\n\t\t}\n\n\t\t// Hash and store the password.\n\t\t$meta['password'] = wp_hash_password( $password );\n\n\t\t// Get signup data.\n\t\t$signup_field_data = (array) $request->get_param( 'signup_field_data' );\n\n\t\t// Store the profile field data.\n\t\tif ( bp_is_active( 'xprofile' ) ) {\n\t\t\t$profile_field_ids = array();\n\t\t\t$args              = array(\n\t\t\t\t'signup_fields_only' => true,\n\t\t\t\t'fetch_fields'       => true,\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * Get signup fields.\n\t\t\t *\n\t\t\t * Let's not use `bp_xprofile_get_groups`, since `BP_XProfile_Data_Template` handles signup fields better.\n\t\t\t */\n\t\t\t$template_query = new BP_XProfile_Data_Template( $args );\n\t\t\t$signup_group   = $template_query->groups[0];\n\n\t\t\tforeach ( $signup_group->fields as $field ) {\n\n\t\t\t\t// Skip field if it's already in the profile field IDs.\n\t\t\t\tif ( in_array( $field->id, $profile_field_ids, true ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tforeach ( $signup_field_data as $field_data ) {\n\t\t\t\t\t$field_id         = (int) $field_data['field_id'];\n\t\t\t\t\t$field_value      = $field_data['value'];\n\t\t\t\t\t$field_visibility = 'public';\n\n\t\t\t\t\tif ( isset( $field_data['visibility'] ) ) {\n\t\t\t\t\t\t$field_visibility = $field_data['visibility'];\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( $field_id !== $field->id ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( (bool) $field->is_required && empty( $field_value ) ) {\n\t\t\t\t\t\treturn new WP_Error(\n\t\t\t\t\t\t\t'bp_rest_signup_field_required',\n\t\t\t\t\t\t\tsprintf(\n\t\t\t\t\t\t\t\t/* translators: %s: Field name. */\n\t\t\t\t\t\t\t\t__( 'The %s field, and its value, are required.', 'buddypress' ),\n\t\t\t\t\t\t\t\t$field->name\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tarray( 'status' => 500 )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t$profile_field_ids[] = $field_id;\n\t\t\t\t\t$field_value         = array_map( 'trim', explode( ', ', $field_value ) );\n\n\t\t\t\t\tif ( false === (bool) $field->type_obj->supports_multiple_defaults ) {\n\t\t\t\t\t\t$field_value = reset( $field_value );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! empty( $field_value ) ) {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Handle datebox field values.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * We expect a date in the format 'Y-m-d'.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif ( 'datebox' === $field->type_obj->name ) {\n\t\t\t\t\t\t\t// @todo update to use `gmdate` when BP core does it too.\n\t\t\t\t\t\t\t$field_value = date( 'Y-m-d H:i:s', strtotime( $field_value ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$meta[ 'field_' . $field_id ] = $field_value;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! empty( $field_visibility ) ) {\n\t\t\t\t\t\t$meta[ 'field_' . $field_id . '_visibility' ] = $field_visibility;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check if the required field is filled.\n\t\t\t\tif ( ! in_array( $field->id, $profile_field_ids, true ) && (bool) $field->is_required ) {\n\t\t\t\t\treturn new WP_Error(\n\t\t\t\t\t\t'bp_rest_signup_field_required',\n\t\t\t\t\t\tsprintf(\n\t\t\t\t\t\t\t/* translators: %s: Field name. */\n\t\t\t\t\t\t\t__( 'The %s field is required.', 'buddypress' ),\n\t\t\t\t\t\t\t$field->name\n\t\t\t\t\t\t),\n\t\t\t\t\t\tarray( 'status' => 500 )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Store the profile field ID's in meta.\n\t\t\t$meta['profile_field_ids'] = implode( ',', array_unique( wp_parse_id_list( $profile_field_ids ) ) );\n\t\t}\n\n\t\tif ( is_multisite() ) {\n\t\t\t// On Multisite, use the WordPress way to generate the activation key.\n\t\t\t$activation_key = substr( md5( time() . wp_rand() . $wp_key_suffix ), 0, 16 );\n\n\t\t\tif ( $site_title && $site_name ) {\n\t\t\t\t/** This filter is documented in wp-includes/ms-functions.php */\n\t\t\t\t$meta = apply_filters( 'signup_site_meta', $meta, $domain, $path, $site_title, $user_login, $user_email, $activation_key );\n\t\t\t} else {\n\t\t\t\t/** This filter is documented in wp-includes/ms-functions.php */\n\t\t\t\t$meta = apply_filters( 'signup_user_meta', $meta, $user_login, $user_email, $activation_key );\n\t\t\t}\n\t\t} else {\n\t\t\t$activation_key = wp_generate_password( 32, false );\n\t\t}\n\n\t\t/**\n\t\t * Filters the user meta used for signup.\n\t\t *\n\t\t * @param array $meta Array of user meta to add to signup.\n\t\t */\n\t\t$meta = apply_filters( 'bp_signup_usermeta', $meta );\n\n\t\t/**\n\t\t * Allow plugins to add their signup meta specific to the BP REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array           $meta    The signup meta.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$meta = apply_filters( 'bp_rest_signup_create_item_meta', $meta, $request );\n\n\t\t$signup_args = array(\n\t\t\t'user_login'     => $user_login,\n\t\t\t'user_email'     => $user_email,\n\t\t\t'activation_key' => $activation_key,\n\t\t\t'domain'         => $domain,\n\t\t\t'path'           => $path,\n\t\t\t'title'          => $site_title,\n\t\t\t'meta'           => $meta,\n\t\t);\n\n\t\t// Add signup.\n\t\t$id = \\BP_Signup::add( $signup_args );\n\n\t\tif ( ! is_numeric( $id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_signup_cannot_create',\n\t\t\t\t__( 'Cannot create new signup.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$signup        = $this->get_signup_object( $id );\n\t\t$signup_update = $this->update_additional_fields_for_object( $signup, $request );\n\n\t\tif ( is_wp_error( $signup_update ) ) {\n\t\t\treturn $signup_update;\n\t\t}\n\n\t\tif ( is_multisite() ) {\n\t\t\tif ( $site_title && $site_name ) {\n\t\t\t\t/** This action is documented in wp-includes/ms-functions.php */\n\t\t\t\tdo_action( 'after_signup_site', $signup->domain, $signup->path, $signup->title, $signup->user_login, $signup->user_email, $signup->activation_key, $signup->meta );\n\t\t\t} else {\n\t\t\t\t/** This action is documented in wp-includes/ms-functions.php */\n\t\t\t\tdo_action( 'after_signup_user', $signup->user_login, $signup->user_email, $signup->activation_key, $signup->meta );\n\t\t\t}\n\t\t\t/** This filter is documented in bp-members/bp-members-functions.php */\n\t\t} elseif ( apply_filters( 'bp_core_signup_send_activation_key', true, false, $signup->user_email, $signup->activation_key, $signup->meta ) ) {\n\t\t\t$salutation = $signup->user_login;\n\t\t\tif ( isset( $signup->user_name ) && $signup->user_name ) {\n\t\t\t\t$salutation = $signup->user_name;\n\t\t\t}\n\n\t\t\tbp_core_signup_send_validation_email( false, $signup->user_email, $signup->activation_key, $salutation );\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $signup, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a signup item is created via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Signup        $signup   The created signup.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_signup_create_item', $signup, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to create a signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\n\t\t/**\n\t\t * Filter the signup `create_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true   $value Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_create_item_permissions_check', true, $request );\n\t}\n\n\t/**\n\t * Delete a signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the signup before it's deleted.\n\t\t$signup   = $this->get_signup_object( $request->get_param( 'id' ) );\n\t\t$previous = $this->prepare_item_for_response( $signup, $request );\n\t\t$deleted  = BP_Signup::delete( array( $signup->id ) );\n\n\t\tif ( ! $deleted ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_signup_cannot_delete',\n\t\t\t\t__( 'Could not delete signup.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a signup is deleted via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Signup        $signup   The deleted signup.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_signup_delete_item', $signup, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the signup `delete_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Activate a signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function activate_item( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the activation key.\n\t\t$activation_key = $request->get_param( 'activation_key' );\n\n\t\t// Get the signup to activate thanks to the activation key.\n\t\t$signup    = $this->get_signup_object( $activation_key );\n\t\t$activated = bp_core_activate_signup( $activation_key );\n\n\t\tif ( ! $activated ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_signup_activate_fail',\n\t\t\t\t__( 'Fail to activate the signup.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $signup, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a signup is activated via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param BP_Signup        $signup   The activated signup.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_signup_activate_item', $signup, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to activate a signup.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function activate_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_invalid_activation_key',\n\t\t\t__( 'Invalid activation key.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => 404,\n\t\t\t)\n\t\t);\n\n\t\t// Get the activation key.\n\t\t$activation_key = $request->get_param( 'activation_key' );\n\n\t\t// Check the activation key is valid.\n\t\tif ( $this->get_signup_object( $activation_key ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the signup `activate_item` permissions check.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_activate_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Resend the activation email.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function signup_resend_activation_email( $request ) {\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$signup_id = $request->get_param( 'id' );\n\t\t$send      = \\BP_Signup::resend( array( $signup_id ) );\n\n\t\tif ( ! empty( $send['errors'] ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_signup_resend_activation_email_fail',\n\t\t\t\t__( 'Your account has already been activated.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( array( 'sent' => true ) );\n\n\t\t/**\n\t\t * Fires after an activation email was (re)sent via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_signup_resend_activation_email', $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to resend the activation email.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function signup_resend_activation_email_permissions_check( $request ) {\n\t\t$retval = true;\n\t\t$signup = $this->get_signup_object( $request->get_param( 'id' ) );\n\n\t\tif ( empty( $signup ) ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid signup id.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the signup resend activation email permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_resend_activation_email_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares signup to return as an object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param  BP_Signup       $signup  Signup object.\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $signup, $request ) {\n\t\t$data = array(\n\t\t\t'id'             => (int) $signup->id,\n\t\t\t'user_login'     => $signup->user_login,\n\t\t\t'registered'     => bp_rest_prepare_date_response( $signup->registered, get_date_from_gmt( $signup->registered ) ),\n\t\t\t'registered_gmt' => bp_rest_prepare_date_response( $signup->registered ),\n\t\t);\n\n\t\t// The user name is only available when the XProfile component is active.\n\t\tif ( isset( $signup->user_name ) ) {\n\t\t\t$data['user_name'] = $signup->user_name;\n\t\t}\n\n\t\t$context = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\n\t\tif ( 'edit' === $context ) {\n\t\t\t$data['user_email']    = $signup->user_email;\n\t\t\t$data['date_sent']     = bp_rest_prepare_date_response( $signup->date_sent, get_date_from_gmt( $signup->date_sent ) );\n\t\t\t$data['date_sent_gmt'] = bp_rest_prepare_date_response( $signup->date_sent );\n\t\t\t$data['count_sent']    = (int) $signup->count_sent;\n\n\t\t\tif ( is_multisite() && $signup->domain && $signup->path && $signup->title ) {\n\t\t\t\tif ( is_subdomain_install() ) {\n\t\t\t\t\t$domain_parts = explode( '.', $signup->domain );\n\t\t\t\t\t$site_name    = reset( $domain_parts );\n\t\t\t\t} else {\n\t\t\t\t\t$domain_parts = explode( '/', $signup->path );\n\t\t\t\t\t$site_name    = end( $domain_parts );\n\t\t\t\t}\n\n\t\t\t\t$data['site_name']     = $site_name;\n\t\t\t\t$data['site_title']    = $signup->title;\n\t\t\t\t$data['site_public']   = isset( $signup->meta['public'] ) ? (bool) $signup->meta['public'] : true;\n\t\t\t\t$data['site_language'] = isset( $signup->meta['WPLANG'] ) ? $signup->meta['WPLANG'] : get_locale();\n\t\t\t}\n\n\t\t\t// Remove the password from meta.\n\t\t\tif ( isset( $signup->meta['password'] ) ) {\n\t\t\t\tunset( $signup->meta['password'] );\n\t\t\t}\n\n\t\t\t$data['meta'] = $signup->meta;\n\t\t}\n\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t$response->add_links( $this->prepare_links( $signup ) );\n\n\t\t/**\n\t\t * Filter the signup response returned from the API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  Request used to generate the response.\n\t\t * @param BP_Signup         $signup   Signup object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_prepare_value', $response, $request, $signup );\n\t}\n\n\t/**\n\t * Prepares links for the signup request.\n\t *\n\t * @param BP_Signup $signup The signup object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $signup ) {\n\t\t$base  = sprintf( '/%1$s/%2$s/', $this->namespace, $this->rest_base );\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . (int) $signup->id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\tif ( is_user_logged_in() && bp_is_active( 'xprofile' ) && ! empty( $signup->meta['profile_field_ids'] ) ) {\n\t\t\t$xprofile_field_ids = explode( ',', $signup->meta['profile_field_ids'] );\n\t\t\t$xprofile_field_ids = wp_parse_id_list( $xprofile_field_ids );\n\n\t\t\tforeach ( $xprofile_field_ids as $field_id ) {\n\t\t\t\t$xprofile_field_base = sprintf( '%1$s/%2$s/', $this->namespace, buddypress()->profile->id . '/fields' );\n\n\t\t\t\t$links[ $field_id ] = array(\n\t\t\t\t\t'href'       => rest_url( $xprofile_field_base . $field_id ),\n\t\t\t\t\t'embeddable' => true,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @param array     $links  The prepared links of the REST response.\n\t\t * @param BP_Signup $signup The signup object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_prepare_links', $links, $signup );\n\t}\n\n\t/**\n\t * Get signup object.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param int|string $identifier Signup identifier.\n\t * @return BP_Signup|false\n\t */\n\tpublic function get_signup_object( $identifier ) {\n\t\tif ( is_numeric( $identifier ) ) {\n\t\t\t$signup_args['include'] = array( intval( $identifier ) );\n\t\t} elseif ( is_email( $identifier ) ) {\n\t\t\t$signup_args['usersearch'] = $identifier;\n\t\t} else {\n\t\t\t// The activation key is used when activating a signup.\n\t\t\t$signup_args['activation_key'] = $identifier;\n\t\t}\n\n\t\t// Get signups.\n\t\t$signups = \\BP_Signup::get( $signup_args );\n\n\t\tif ( ! empty( $signups['signups'] ) ) {\n\t\t\treturn reset( $signups['signups'] );\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Check a user password for the REST API.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param string $value The password submitted in the request.\n\t * @return string|WP_Error The sanitized password, if valid, otherwise an error.\n\t */\n\tpublic function check_user_password( $value ) {\n\t\t$password = (string) $value;\n\n\t\tif ( empty( $password ) || false !== strpos( $password, '\\\\' ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'rest_user_invalid_password',\n\t\t\t\t__( 'Passwords cannot be empty or contain the \"\\\\\" character.', 'buddypress' ),\n\t\t\t\tarray( 'status' => 400 )\n\t\t\t);\n\t\t}\n\n\t\treturn $password;\n\t}\n\n\t/**\n\t * Is it possible to signup with a blog?\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return bool True if blog signup is allowed. False otherwise.\n\t */\n\tpublic function is_blog_signup_allowed() {\n\t\t$active_signup = get_network_option( get_main_network_id(), 'registration' );\n\n\t\treturn ( 'blog' === $active_signup || 'all' === $active_signup );\n\t}\n\n\t/**\n\t * Get site's available locales.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array The list of available locales.\n\t */\n\tpublic function get_available_languages() {\n\t\t/** This filter is documented in wp-signup.php */\n\t\t$languages = (array) apply_filters( 'signup_get_available_languages', get_available_languages() );\n\t\treturn array_intersect_assoc( $languages, get_available_languages() );\n\t}\n\n\t/**\n\t * Edit the type of the some properties for the CREATABLE & EDITABLE methods.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param string $method HTTP method of the request. Default is WP_REST_Server::CREATABLE.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\n\t\t\t// The password is required when creating a signup.\n\t\t\t$args['password'] = array(\n\t\t\t\t'description' => __( 'Password for the new user (never included).', 'buddypress' ),\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array(), // Password is never displayed.\n\t\t\t\t'required'    => true,\n\t\t\t);\n\n\t\t\tif ( bp_is_active( 'xprofile' ) ) {\n\t\t\t\t$args['signup_field_data'] = array(\n\t\t\t\t\t'description'       => __( 'The XProfile field data for the new user.', 'buddypress' ),\n\t\t\t\t\t'type'              => 'array',\n\t\t\t\t\t'context'           => array( 'edit' ),\n\t\t\t\t\t'required'          => true,\n\t\t\t\t\t'items'             => array(\n\t\t\t\t\t\t'type'       => 'object',\n\t\t\t\t\t\t'properties' => array(\n\t\t\t\t\t\t\t'field_id'   => array(\n\t\t\t\t\t\t\t\t'description'       => __( 'The XProfile field ID.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'required'          => true,\n\t\t\t\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'value'      => array(\n\t\t\t\t\t\t\t\t'description'       => __( 'The value(s) (comma separated list of values needs to be used in case of multiple values) for the field data.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'default'           => '',\n\t\t\t\t\t\t\t\t'required'          => false,\n\t\t\t\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'visibility' => array(\n\t\t\t\t\t\t\t\t'description'       => __( 'The visibility for the XProfile field.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'required'          => false,\n\t\t\t\t\t\t\t\t'default'           => 'public',\n\t\t\t\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t\t\t'enum'              => array_keys( bp_xprofile_get_visibility_levels() ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'validate_callback' => static function ( $data ) {\n\t\t\t\t\t\tif ( ! is_array( $data ) || empty( $data ) ) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn $data;\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * We do not need the meta for the create item method\n\t\t\t * as we are building it inside this method.\n\t\t\t */\n\t\t\tunset( $args['meta'] );\n\t\t} elseif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key = 'update_item';\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_signup_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the signup schema, conforming to JSON Schema.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_signup',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'             => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the signup.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'user_login'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The username of the user the signup is for.', 'buddypress' ),\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'user_email'     => array(\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The email for the user the signup is for.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'activation_key' => array(\n\t\t\t\t\t\t'context'     => array(), // The activation key is sent to the user via email.\n\t\t\t\t\t\t'description' => __( 'Activation key of the signup.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'registered'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The registered date for the user, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'registered_gmt' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The registered date for the user, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_sent'      => array(\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the activation email was sent to the user, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_sent_gmt'  => array(\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the activation email was sent to the user, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'count_sent'     => array(\n\t\t\t\t\t\t'description' => __( 'The number of times the activation email was sent to the user.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'meta'           => array(\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The signup meta information', 'buddypress' ),\n\t\t\t\t\t\t'type'        => array( 'object', 'null' ),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// This will be fully removed in V2.\n\t\t\tif ( bp_is_active( 'xprofile' ) ) {\n\t\t\t\t$schema['properties']['user_name'] = array(\n\t\t\t\t\t'context'     => array(),\n\t\t\t\t\t'description' => __( 'The new user\\'s full name. (Deprecated)', 'buddypress' ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'readonly'    => true,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( is_multisite() && $this->is_blog_signup_allowed() ) {\n\t\t\t\t$schema['properties']['site_name'] = array(\n\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t'description' => __( 'Unique site name (slug) of the new user\\'s child site.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'default'     => '',\n\t\t\t\t);\n\n\t\t\t\t$schema['properties']['site_title'] = array(\n\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t'description' => __( 'Title of the new user\\'s child site.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'default'     => '',\n\t\t\t\t);\n\n\t\t\t\t$schema['properties']['site_public'] = array(\n\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t'description' => __( 'Search engine visibility of the new user\\'s site.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t'default'     => true,\n\t\t\t\t);\n\n\t\t\t\t$schema['properties']['site_language'] = array(\n\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t'description' => __( 'Language to use for the new user\\'s site.', 'buddypress' ),\n\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t'default'     => get_locale(),\n\t\t\t\t\t'enum'        => array_merge( array( get_locale() ), $this->get_available_languages() ),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Cache current schema here.\n\t\t\t$this->schema = $schema;\n\t\t}\n\n\t\t/**\n\t\t * Filters the signup schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for collections.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\tunset( $params['page'], $params['per_page'], $params['search'] );\n\n\t\t$params['number'] = array(\n\t\t\t'description'       => __( 'Total number of signups to return.', 'buddypress' ),\n\t\t\t'default'           => 10,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['offset'] = array(\n\t\t\t'description'       => __( 'Offset the result set by a specific number of items.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['include'] = array(\n\t\t\t'description'       => __( 'Ensure result set includes specific IDs.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['orderby'] = array(\n\t\t\t'description'       => __( 'Order by a specific parameter (default: signup_id).', 'buddypress' ),\n\t\t\t'default'           => 'signup_id',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'signup_id', 'login', 'email', 'registered', 'activated' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['order'] = array(\n\t\t\t'description'       => __( 'Order sort attribute ascending or descending.', 'buddypress' ),\n\t\t\t'default'           => 'desc',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'asc', 'desc' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_login'] = array(\n\t\t\t'description'       => __( 'Specific user login to return.', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_signup_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-messages/classes/class-bp-rest-messages-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Messages_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Messages endpoints.\n *\n * /messages/\n * /messages/{thread_id}\n * /messages/starred/{message_id}\n *\n * @since 0.1.0\n */\nclass BP_REST_Messages_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Messages_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = buddypress()->messages->id;\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\t// Attention: (?P<id>[\\d]+) is the placeholder for **Thread** ID, not the Message ID one.\n\t\t$thread_endpoint = '/' . $this->rest_base . '/(?P<id>[\\d]+)';\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t$thread_endpoint,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::DELETABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\t// Register the starred route.\n\t\tif ( bp_is_active( 'messages', 'star' ) ) {\n\t\t\t// Attention: (?P<id>[\\d]+) is the placeholder for **Message** ID, not the Thread ID one.\n\t\t\t$starred_endpoint = '/' . $this->rest_base . '/' . bp_get_messages_starred_slug() . '/(?P<id>[\\d]+)';\n\n\t\t\tregister_rest_route(\n\t\t\t\t$this->namespace,\n\t\t\t\t$starred_endpoint,\n\t\t\t\tarray(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t\t'callback'            => array( $this, 'update_starred' ),\n\t\t\t\t\t\t'permission_callback' => array( $this, 'update_starred_permissions_check' ),\n\t\t\t\t\t),\n\t\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Retrieve threads.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'user_id'             => $request->get_param( 'user_id' ),\n\t\t\t'box'                 => $request->get_param( 'box' ),\n\t\t\t'type'                => $request->get_param( 'type' ),\n\t\t\t'page'                => $request->get_param( 'page' ),\n\t\t\t'per_page'            => $request->get_param( 'per_page' ),\n\t\t\t'search_terms'        => $request->get_param( 'search' ),\n\t\t\t'recipients_page'     => $request->get_param( 'recipients_page' ),\n\t\t\t'recipients_per_page' => $request->get_param( 'recipients_per_page' ),\n\t\t\t'messages_page'       => $request->get_param( 'messages_page' ),\n\t\t\t'messages_per_page'   => $request->get_param( 'messages_per_page' ),\n\t\t);\n\n\t\t// Include the meta_query for starred messages.\n\t\tif ( 'starred' === $args['box'] ) {\n\t\t\t$args['meta_query'] = array( // phpcs:ignore\n\t\t\t\tarray(\n\t\t\t\t\t'key'   => 'starred_by_user',\n\t\t\t\t\t'value' => $args['user_id'],\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_messages_get_items_query_args', $args, $request );\n\n\t\t// Actually, query it.\n\t\t$messages_box = new BP_Messages_Box_Template( $args );\n\n\t\t$retval = array();\n\t\tforeach ( (array) $messages_box->threads as $thread ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $thread, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $messages_box->total_thread_count, $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a thread is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Messages_Box_Template  $messages_box Fetched thread.\n\t\t * @param WP_REST_Response          $response     The response data.\n\t\t * @param WP_REST_Request           $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_messages_get_items', $messages_box, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to thread items.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$user = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\n\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( (int) bp_loggedin_user_id() === $user->ID || bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you cannot view the messages.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the messages `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Get a single thread.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_item( $request ) {\n\t\t$args = array(\n\t\t\t'recipients_page'     => $request->get_param( 'recipients_page' ),\n\t\t\t'recipients_per_page' => $request->get_param( 'recipients_per_page' ),\n\t\t\t'page'                => $request->get_param( 'messages_page' ),\n\t\t\t'per_page'            => $request->get_param( 'messages_per_page' ),\n\t\t\t'order'               => $request->get_param( 'order' ),\n\t\t\t'user_id'             => $request->get_param( 'user_id' ),\n\t\t);\n\n\t\tif ( empty( $args['user_id'] ) ) {\n\t\t\t$args['user_id'] = bp_loggedin_user_id();\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_messages_get_item_query_args', $args, $request );\n\n\t\t$thread = new BP_Messages_Thread(\n\t\t\t$request->get_param( 'id' ),\n\t\t\t'ASC', // not used.\n\t\t\t$args\n\t\t);\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $thread, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\t\t$response = bp_rest_response_add_total_headers( $response, $thread->messages_total_count, $args['per_page'] );\n\n\t\t/**\n\t\t * Fires after a thread is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Messages_Thread $thread   Thread object.\n\t\t * @param WP_REST_Response   $response The response data.\n\t\t * @param WP_REST_Request    $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_messages_get_item', $thread, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to a thread item.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$error = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to see this thread.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\t$retval  = $error;\n\t\t$user_id = bp_loggedin_user_id();\n\t\tif ( ! empty( $request->get_param( 'user_id' ) ) ) {\n\t\t\t$user_id = $request->get_param( 'user_id' );\n\t\t}\n\n\t\t$id = $request->get_param( 'id' );\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$thread = BP_Messages_Thread::is_valid( $id );\n\n\t\t\tif ( empty( $thread ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Sorry, this thread does not exist.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) || messages_check_thread_access( $id, $user_id ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the messages `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Init a Messages Thread or add a reply to an existing Thread.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Create the message or the reply.\n\t\t$thread_id = messages_new_message( $this->prepare_item_for_database( $request ) );\n\n\t\t// Validate it created a Thread or was added to it.\n\t\tif ( false === $thread_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_messages_create_failed',\n\t\t\t\t__( 'There was an error trying to create the message.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Make sure to get the newest message to update REST Additional fields.\n\t\t$thread        = $this->get_thread_object( $thread_id );\n\t\t$last_message  = wp_list_filter( $thread->messages, array( 'id' => $thread->last_message_id ) );\n\t\t$last_message  = reset( $last_message );\n\t\t$fields_update = $this->update_additional_fields_for_object( $last_message, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $thread, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a message is created via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Messages_Thread $thread   Thread object.\n\t\t * @param WP_REST_Response   $response The response data.\n\t\t * @param WP_REST_Request    $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_messages_create_item', $thread, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to create a message.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to create a message.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\t$thread_id = (int) $request->get_param( 'id' );\n\n\t\t\t// It's an existing thread.\n\t\t\tif ( $thread_id ) {\n\t\t\t\tif ( bp_current_user_can( 'bp_moderate' ) || ( messages_is_valid_thread( $thread_id ) && messages_check_thread_access( $thread_id ) ) ) {\n\t\t\t\t\t$retval = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// It's a new thread.\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the messages `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update metadata for one of the messages of the thread.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Updated user id.\n\t\t$updated_user_id = bp_loggedin_user_id();\n\t\tif ( ! empty( $request->get_param( 'user_id' ) ) ) {\n\t\t\t$updated_user_id = $request->get_param( 'user_id' );\n\t\t}\n\n\t\t// Get the thread.\n\t\t$thread = $this->get_thread_object( $request->get_param( 'id' ), $updated_user_id );\n\t\t$error  = new WP_Error(\n\t\t\t'bp_rest_messages_update_failed',\n\t\t\t__( 'There was an error trying to update the message.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => 500,\n\t\t\t)\n\t\t);\n\n\t\t// Is someone updating the thread status?\n\t\t$thread_status_update = ( (bool) $request->get_param( 'read' ) || (bool) $request->get_param( 'unread' ) );\n\n\t\t// Mark thread as read.\n\t\tif ( true === (bool) $request->get_param( 'read' ) ) {\n\t\t\tmessages_mark_thread_read( $thread->thread_id, $updated_user_id );\n\t\t}\n\n\t\t// Mark thread as unread.\n\t\tif ( true === (bool) $request->get_param( 'unread' ) ) {\n\t\t\tmessages_mark_thread_unread( $thread->thread_id, $updated_user_id );\n\t\t}\n\n\t\t// By default use the last message.\n\t\t$message_id = $thread->last_message_id;\n\t\tif ( $request->get_param( 'message_id' ) ) {\n\t\t\t$message_id = $request->get_param( 'message_id' );\n\t\t}\n\n\t\t$updated_message = wp_list_filter( $thread->messages, array( 'id' => $message_id ) );\n\t\t$updated_message = reset( $updated_message );\n\n\t\t/**\n\t\t * Filter here to allow more users to edit the message meta (eg: the recipients).\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param boolean             $value           Whether the user can edit the message meta.\n\t\t *                                             By default: only the sender and a community moderator can.\n\t\t * @param BP_Messages_Message $updated_message The updated message object.\n\t\t * @param WP_REST_Request     $request         Full details about the request.\n\t\t */\n\t\t$can_edit_item_meta = apply_filters(\n\t\t\t'bp_rest_messages_can_edit_item_meta',\n\t\t\tbp_loggedin_user_id() === $updated_message->sender_id || bp_current_user_can( 'bp_moderate' ),\n\t\t\t$updated_message,\n\t\t\t$request\n\t\t);\n\n\t\t// The message must exist in the thread, and the logged in user must be the sender.\n\t\tif (\n\t\t\tfalse === $thread_status_update\n\t\t\t&& (\n\t\t\t\t! isset( $updated_message->id )\n\t\t\t\t|| ! $updated_message->id\n\t\t\t\t|| ! $can_edit_item_meta\n\t\t\t)\n\t\t) {\n\t\t\treturn $error;\n\t\t}\n\n\t\t$fields_update = $this->update_additional_fields_for_object( $updated_message, $request );\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t// Get the updated thread object.\n\t\t$thread = $this->get_thread_object( $thread->thread_id, $updated_user_id );\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $thread, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a thread or a message is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Messages_Message $updated_message The updated message.\n\t\t * @param WP_REST_Response    $response        The response data.\n\t\t * @param WP_REST_Request     $request         The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_messages_update_item', $updated_message, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a message.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the message `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Adds or removes the message from the current user's starred box.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_starred( $request ) {\n\t\t$message = $this->get_message_object( $request->get_param( 'id' ) );\n\t\t$user_id = bp_loggedin_user_id();\n\t\t$result  = false;\n\t\t$action  = 'star';\n\t\t$info    = __( 'Sorry, you cannot add the message to your starred box.', 'buddypress' );\n\n\t\tif ( bp_messages_is_message_starred( $message->id, $user_id ) ) {\n\t\t\t$action = 'unstar';\n\t\t\t$info   = __( 'Sorry, you cannot remove the message from your starred box.', 'buddypress' );\n\t\t}\n\n\t\t$result = bp_messages_star_set_action(\n\t\t\tarray(\n\t\t\t\t'user_id'    => $user_id,\n\t\t\t\t'message_id' => $message->id,\n\t\t\t\t'action'     => $action,\n\t\t\t)\n\t\t);\n\n\t\tif ( ! $result ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_starred_message',\n\t\t\t\t$info,\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Prepare the message for the REST response.\n\t\t$data = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_message_for_response( $message, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $data );\n\n\t\t/**\n\t\t * Fires after a message is starred/unstarred via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Messages_Message $message  Message object.\n\t\t * @param string              $action   Informs about the update performed.\n\t\t *                                      Possible values are `star` or `unstar`.\n\t\t * @param WP_REST_Response    $response The response data.\n\t\t * @param WP_REST_Request     $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_message_update_starred_item', $message, $action, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update user starred messages.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_starred_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to star/unstar messages.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( ! is_user_logged_in() ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to star/unstar a message.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\t$thread_id = messages_get_message_thread_id( $request->get_param( 'id' ) ); // This is a message id.\n\n\t\t\tif ( empty( $thread_id ) ) {\n\t\t\t\treturn new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Sorry, the thread of this message does not exist.', 'buddypress' ),\n\t\t\t\t\tarray( 'status' => 404 )\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( messages_check_thread_access( $thread_id ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the message `update_starred` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_update_starred_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete a thread.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$user_id = bp_loggedin_user_id();\n\t\tif ( ! empty( $request->get_param( 'user_id' ) ) ) {\n\t\t\t$user_id = $request->get_param( 'user_id' );\n\t\t}\n\n\t\t// Get the thread before it's deleted.\n\t\t$thread   = $this->get_thread_object( $request->get_param( 'id' ), $user_id );\n\t\t$previous = $this->prepare_item_for_response( $thread, $request );\n\n\t\t// Check the user is one of the recipients.\n\t\tif ( ! in_array( $user_id, wp_parse_id_list( wp_list_pluck( $thread->get_recipients(), 'user_id' ) ), true ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Delete a thread.\n\t\tif ( false === messages_delete_thread( $thread->thread_id, $user_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_messages_delete_thread_failed',\n\t\t\t\t__( 'There was an error trying to delete the thread.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a thread is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Messages_Thread $thread   The thread object.\n\t\t * @param WP_REST_Response   $response The response data.\n\t\t * @param WP_REST_Request    $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_messages_delete_item', $thread, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a thread.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the thread `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepare a message for create.\n\t *\n\t * @since 6.0.0\n\t *\n\t * @param WP_REST_Request $request The request sent to the API.\n\t * @return stdClass\n\t */\n\tprotected function prepare_item_for_database( $request ) {\n\t\t$prepared_thread = new stdClass();\n\t\t$schema          = $this->get_item_schema();\n\t\t$thread          = $this->get_thread_object( $request->get_param( 'id' ) );\n\n\t\tif ( ! empty( $schema['properties']['id'] ) && ! empty( $request->get_param( 'id' ) ) ) {\n\t\t\t$prepared_thread->thread_id = $request->get_param( 'id' );\n\t\t} elseif ( ! empty( $thread->thread_id ) ) {\n\t\t\t$prepared_thread->thread_id = $thread->thread_id;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['sender_id'] ) && ! empty( $request->get_param( 'sender_id' ) ) ) {\n\t\t\t$prepared_thread->sender_id = $thread->sender_id;\n\t\t} elseif ( ! empty( $thread->sender_id ) ) {\n\t\t\t$prepared_thread->sender_id = $thread->sender_id;\n\t\t} else {\n\t\t\t$prepared_thread->sender_id = bp_loggedin_user_id();\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['message'] ) && ! empty( $request->get_param( 'message' ) ) ) {\n\t\t\t$prepared_thread->content = $request->get_param( 'message' );\n\t\t} elseif ( ! empty( $thread->message ) ) {\n\t\t\t$prepared_thread->message = $thread->message;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['subject'] ) && ! empty( $request->get_param( 'subject' ) ) ) {\n\t\t\t$prepared_thread->subject = $request->get_param( 'subject' );\n\t\t} elseif ( ! empty( $thread->subject ) ) {\n\t\t\t$prepared_thread->subject = $thread->subject;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['recipients'] ) && ! empty( $request->get_param( 'recipients' ) ) ) {\n\t\t\t$prepared_thread->recipients = $request->get_param( 'recipients' );\n\t\t} elseif ( ! empty( $thread->recipients ) ) {\n\t\t\t$prepared_thread->recipients = wp_parse_id_list( wp_list_pluck( $thread->recipients, 'user_id' ) );\n\t\t}\n\n\t\t/**\n\t\t * Filters a message before it is inserted via the REST API.\n\t\t *\n\t\t * @since 6.0.0\n\t\t *\n\t\t * @param stdClass        $prepared_thread An object prepared for inserting into the database.\n\t\t * @param WP_REST_Request $request Request object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_message_pre_insert_value', $prepared_thread, $request );\n\t}\n\n\t/**\n\t * Prepares message data for the REST response.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Messages_Message $message The Message object.\n\t * @param WP_REST_Request     $request Full details about the request.\n\t * @return array The Message data for the REST response.\n\t */\n\tpublic function prepare_message_for_response( $message, $request ) {\n\t\t$data = array(\n\t\t\t'id'        => (int) $message->id,\n\t\t\t'thread_id' => (int) $message->thread_id,\n\t\t\t'sender_id' => (int) $message->sender_id,\n\t\t\t'subject'   => array(\n\t\t\t\t'raw'      => $message->subject,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_message_thread_subject', $message->subject ),\n\t\t\t),\n\t\t\t'message'   => array(\n\t\t\t\t'raw'      => $message->message,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_the_thread_message_content', $message->message ),\n\t\t\t),\n\t\t\t'date_sent' => bp_rest_prepare_date_response( $message->date_sent ),\n\t\t);\n\n\t\tif ( bp_is_active( 'messages', 'star' ) ) {\n\t\t\t$user_id = bp_loggedin_user_id();\n\n\t\t\tif ( ! empty( $request->get_param( 'user_id' ) ) ) {\n\t\t\t\t$user_id = (int) $request->get_param( 'user_id' );\n\t\t\t}\n\n\t\t\t$data['is_starred'] = bp_messages_is_message_starred( $data['id'], $user_id );\n\t\t}\n\n\t\t$context = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data    = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data    = $this->filter_response_by_context( $data, $context );\n\n\t\t/**\n\t\t * Filter a message value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array               $data    The message value for the REST response.\n\t\t * @param BP_Messages_Message $message The Message object.\n\t\t * @param WP_REST_Request     $request Request used to generate the response.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_message_prepare_value', $data, $message, $request );\n\t}\n\n\t/**\n\t * Prepares recipient data for the REST response.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param object          $recipient The recipient object.\n\t * @param WP_REST_Request $request   Full details about the request.\n\t * @return array                     The recipient data for the REST response.\n\t */\n\tpublic function prepare_recipient_for_response( $recipient, $request ) {\n\t\t$display_name = '';\n\t\t$user_info    = get_userdata( (int) $recipient->user_id );\n\n\t\tif ( $user_info instanceof WP_User && ! empty( $user_info->display_name ) ) {\n\t\t\t$display_name = (string) $user_info->display_name;\n\t\t}\n\n\t\t$data = array(\n\t\t\t'id'           => (int) $recipient->id,\n\t\t\t'is_deleted'   => (int) $recipient->is_deleted,\n\t\t\t'name'         => $display_name,\n\t\t\t'sender_only'  => (int) $recipient->sender_only,\n\t\t\t'thread_id'    => (int) $recipient->thread_id,\n\t\t\t'unread_count' => (int) $recipient->unread_count,\n\t\t\t'user_id'      => (int) $recipient->user_id,\n\t\t\t'user_link'    => esc_url( bp_members_get_user_url( $recipient->user_id ) ),\n\t\t);\n\n\t\t// Fetch the user avatar urls (Full & thumb).\n\t\tif ( true === buddypress()->avatar->show_avatars ) {\n\t\t\tforeach ( array( 'full', 'thumb' ) as $type ) {\n\t\t\t\t$data['user_avatars'][ $type ] = bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'item_id' => $recipient->user_id,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t\t'type'    => $type,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter a recipient value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $data      The recipient value for the REST response.\n\t\t * @param object          $recipient The recipient object.\n\t\t * @param WP_REST_Request $request   Request used to generate the response.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_prepare_recipient_value', $data, $recipient, $request );\n\t}\n\n\t/**\n\t * Prepares thread data for return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Messages_Thread $thread  The thread object.\n\t * @param WP_REST_Request    $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $thread, $request ) {\n\t\t$excerpt = '';\n\t\tif ( isset( $thread->last_message_content ) ) {\n\t\t\t$excerpt = wp_strip_all_tags( bp_create_excerpt( $thread->last_message_content, 75 ) );\n\t\t}\n\n\t\t$data = array(\n\t\t\t'id'             => (int) $thread->thread_id,\n\t\t\t'message_id'     => (int) $thread->last_message_id,\n\t\t\t'last_sender_id' => (int) $thread->last_sender_id,\n\t\t\t'subject'        => array(\n\t\t\t\t'raw'      => $thread->last_message_subject,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_message_thread_subject', $thread->last_message_subject ),\n\t\t\t),\n\t\t\t'excerpt'        => array(\n\t\t\t\t'raw'      => $excerpt,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_message_thread_excerpt', $excerpt ),\n\t\t\t),\n\t\t\t'message'        => array(\n\t\t\t\t'raw'      => $thread->last_message_content,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_message_thread_content', $thread->last_message_content ),\n\t\t\t),\n\t\t\t'date'           => bp_rest_prepare_date_response( $thread->last_message_date, get_date_from_gmt( $thread->last_message_date ) ),\n\t\t\t'date_gmt'       => bp_rest_prepare_date_response( $thread->last_message_date ),\n\t\t\t'unread_count'   => ! empty( $thread->unread_count ) ? absint( $thread->unread_count ) : 0,\n\t\t\t'sender_ids'     => (array) $thread->sender_ids,\n\t\t\t'recipients'     => array(),\n\t\t\t'messages'       => array(),\n\t\t);\n\n\t\t// Loop through messages to prepare them for the response.\n\t\tforeach ( $thread->messages as $message ) {\n\t\t\t$data['messages'][] = $this->prepare_message_for_response( $message, $request );\n\t\t}\n\n\t\t// Loop through recipients to prepare them for the response.\n\t\tforeach ( $thread->recipients as $recipient ) {\n\t\t\t$data['recipients'][] = $this->prepare_recipient_for_response( $recipient, $request );\n\t\t}\n\n\t\t// Pluck starred message ids.\n\t\t$data['starred_message_ids'] = array_keys( array_filter( wp_list_pluck( $data['messages'], 'is_starred', 'id' ) ) );\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $thread ) );\n\n\t\t/**\n\t\t * Filter a thread value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response   $response Response generated by the request.\n\t\t * @param WP_REST_Request    $request  Request used to generate the response.\n\t\t * @param BP_Messages_Thread $thread   The thread object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_prepare_value', $response, $request, $thread );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Messages_Thread $thread  Thread object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $thread ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $thread->thread_id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\t// Add star links for each message of the thread.\n\t\tif ( is_user_logged_in() && bp_is_active( 'messages', 'star' ) ) {\n\t\t\t$starred_base = $base . bp_get_messages_starred_slug() . '/';\n\n\t\t\tforeach ( $thread->messages as $message ) {\n\t\t\t\t$links[ $message->id ] = array(\n\t\t\t\t\t'href' => rest_url( $starred_base . $message->id ),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array              $links  The prepared links of the REST response.\n\t\t * @param BP_Messages_Thread $thread The thread object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_prepare_links', $links, $thread );\n\t}\n\n\t/**\n\t * Get the thread object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $thread_id Thread ID.\n\t * @param int $user_id   User ID.\n\t * @return BP_Messages_Thread|string\n\t */\n\tpublic function get_thread_object( $thread_id, $user_id = 0 ) {\n\t\t$args = array();\n\t\tif ( ! empty( $user_id ) ) {\n\t\t\t$args = array( 'user_id' => $user_id );\n\t\t}\n\n\t\t// Validate the thread ID.\n\t\t$thread_id = BP_Messages_Thread::is_valid( $thread_id );\n\n\t\tif ( false === (bool) $thread_id ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn new BP_Messages_Thread( (int) $thread_id, 'ASC', $args );\n\t}\n\n\t/**\n\t * Get the message object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $message_id Message ID.\n\t * @return BP_Messages_Message|string\n\t */\n\tpublic function get_message_object( $message_id ) {\n\t\t$message_object = new BP_Messages_Message( (int) $message_id );\n\n\t\tif ( empty( $message_object->id ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn $message_object;\n\t}\n\n\t/**\n\t * Select the item schema arguments needed for the CREATABLE, EDITABLE and DELETABLE methods.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args                      = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$args['id']['description'] = __( 'ID of the Messages Thread.', 'buddypress' );\n\n\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\n\t\t\t// Edit the Thread ID description and default properties.\n\t\t\t$args['id']['description'] = __( 'ID of the Messages Thread. Required when replying to an existing Thread.', 'buddypress' );\n\t\t\t$args['id']['default']     = 0;\n\n\t\t\t// Add the sender_id argument.\n\t\t\t$args['sender_id'] = array(\n\t\t\t\t'description'       => __( 'The user ID of the Message sender.', 'buddypress' ),\n\t\t\t\t'required'          => false,\n\t\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t\t'type'              => 'integer',\n\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t);\n\n\t\t\t// Edit subject's properties.\n\t\t\t$args['subject']['type']        = 'string';\n\t\t\t$args['subject']['default']     = false;\n\t\t\t$args['subject']['description'] = __( 'Subject of the Message initializing the Thread.', 'buddypress' );\n\n\t\t\t// Edit message's properties.\n\t\t\t$args['message']['type']        = 'string';\n\t\t\t$args['message']['description'] = __( 'Content of the Message to add to the Thread.', 'buddypress' );\n\n\t\t\t// Edit recipients properties.\n\t\t\t$args['recipients']['required']          = true;\n\t\t\t$args['recipients']['items']             = array( 'type' => 'integer' );\n\t\t\t$args['recipients']['sanitize_callback'] = 'wp_parse_id_list';\n\t\t\t$args['recipients']['validate_callback'] = 'rest_validate_request_arg';\n\t\t\t$args['recipients']['description']       = __( 'The list of the recipients user IDs of the Message.', 'buddypress' );\n\n\t\t\t// Remove unused properties for this transport method.\n\t\t\tunset( $args['subject']['properties'], $args['message']['properties'] );\n\n\t\t} else {\n\t\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t\t$key = 'update_item';\n\n\t\t\t\t$args['read'] = array(\n\t\t\t\t\t'description'       => __( 'Whether to mark the thread as read.', 'buddypress' ),\n\t\t\t\t\t'required'          => false,\n\t\t\t\t\t'default'           => false,\n\t\t\t\t\t'type'              => 'boolean',\n\t\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\n\t\t\t\t$args['unread'] = array(\n\t\t\t\t\t'description'       => __( 'Whether to mark the thread as unread.', 'buddypress' ),\n\t\t\t\t\t'required'          => false,\n\t\t\t\t\t'default'           => false,\n\t\t\t\t\t'type'              => 'boolean',\n\t\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\n\t\t\t\t$args['message_id'] = array(\n\t\t\t\t\t'description'       => __( 'By default the latest message of the thread will be updated. Specify this message ID to edit another message of the thread.', 'buddypress' ),\n\t\t\t\t\t'required'          => false,\n\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t\t$key = 'delete_item';\n\n\t\t\t\t$args['user_id'] = array(\n\t\t\t\t\t'description'       => __( 'The user ID to remove from the thread', 'buddypress' ),\n\t\t\t\t\t'required'          => true,\n\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t\t);\n\n\t\t\t\tunset( $args['sender_id'], $args['subject'], $args['message'], $args['recipients'] );\n\t\t\t}\n\n\t\t\tif ( WP_REST_Server::READABLE === $method ) {\n\t\t\t\tunset( $args['sender_id'], $args['subject'], $args['message'], $args['recipients'] );\n\n\t\t\t\t$key = 'get_item';\n\n\t\t\t\t$args['user_id'] = array(\n\t\t\t\t\t'description'       => __( 'The user ID to get the thread for.', 'buddypress' ),\n\t\t\t\t\t'required'          => false,\n\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\n\t\t\t\t$args['recipients_page'] = array(\n\t\t\t\t\t'description'       => __( 'Current page of the recipients collection.', 'buddypress' ),\n\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t'default'           => 1,\n\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t'minimum'           => 1,\n\t\t\t\t);\n\n\t\t\t\t$args['recipients_per_page'] = array(\n\t\t\t\t\t'description'       => __( 'Maximum number of recipients to be returned in result set.', 'buddypress' ),\n\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t'default'           => 10,\n\t\t\t\t\t'minimum'           => 1,\n\t\t\t\t\t'maximum'           => 100,\n\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\n\t\t\t\t$args['messages_page'] = array(\n\t\t\t\t\t'description'       => __( 'Current page of the messages collection.', 'buddypress' ),\n\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t'default'           => 1,\n\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t'minimum'           => 1,\n\t\t\t\t);\n\n\t\t\t\t$args['messages_per_page'] = array(\n\t\t\t\t\t'description'       => __( 'Maximum number of messages to be returned in result set.', 'buddypress' ),\n\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t'default'           => 10,\n\t\t\t\t\t'minimum'           => 1,\n\t\t\t\t\t'maximum'           => 100,\n\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\n\t\t\t\t$args['order'] = array(\n\t\t\t\t\t'description'       => __( 'Order sort attribute ascending or descending.', 'buddypress' ),\n\t\t\t\t\t'default'           => 'asc',\n\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t'enum'              => array( 'asc', 'desc' ),\n\t\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array $args Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_messages_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the message schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_messages',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'message_id'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the latest message of the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'last_sender_id'      => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of latest sender of the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'subject'             => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Title of the latest message of the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Title of the latest message of the Thread, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t\t'default'     => false,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Title of the latest message of the Thread, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t\t'default'     => false,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'excerpt'             => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Summary of the latest message of the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Summary for the latest message of the Thread, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML summary for the latest message of the Thread, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'message'             => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Content of the latest message of the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the latest message of the Thread, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the latest message of the Thread, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'date'                => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Dat of the latest message of the Thread, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_gmt'            => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Date of the latest message of the Thread, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'unread_count'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Total count of unread messages into the Thread for the requested user.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'sender_ids'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The list of user IDs for all messages in the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'integer',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'recipients'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The list of recipient User Objects involved into the Thread.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'object',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'messages'            => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'List of message objects for the thread.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'object',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'starred_message_ids' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'List of starred message IDs.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t'type' => 'integer',\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'default'     => array(),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the message schema.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_message_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for Messages collections.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\t\t$boxes                        = array( 'sentbox', 'inbox' );\n\n\t\tif ( bp_is_active( 'messages', 'star' ) ) {\n\t\t\t$boxes[] = 'starred';\n\t\t}\n\n\t\t$params['box'] = array(\n\t\t\t'description'       => __( 'Filter the result by box.', 'buddypress' ),\n\t\t\t'default'           => 'inbox',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => $boxes,\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['type'] = array(\n\t\t\t'description'       => __( 'Filter the result by thread status.', 'buddypress' ),\n\t\t\t'default'           => 'all',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'all', 'read', 'unread' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Limit result to messages created by a specific user.', 'buddypress' ),\n\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t'type'              => 'integer',\n\t\t\t'required'          => true,\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['recipients_page'] = array(\n\t\t\t'description'       => __( 'Current page of the recipients collection.', 'buddypress' ),\n\t\t\t'type'              => 'integer',\n\t\t\t'default'           => 1,\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t'minimum'           => 1,\n\t\t);\n\n\t\t$params['recipients_per_page'] = array(\n\t\t\t'description'       => __( 'Maximum number of recipients to be returned in result set.', 'buddypress' ),\n\t\t\t'type'              => 'integer',\n\t\t\t'default'           => 10,\n\t\t\t'minimum'           => 1,\n\t\t\t'maximum'           => 100,\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['messages_page'] = array(\n\t\t\t'description'       => __( 'Current page of the messages collection.', 'buddypress' ),\n\t\t\t'type'              => 'integer',\n\t\t\t'default'           => 1,\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t'minimum'           => 1,\n\t\t);\n\n\t\t$params['messages_per_page'] = array(\n\t\t\t'description'       => __( 'Maximum number of messages to be returned in result set.', 'buddypress' ),\n\t\t\t'type'              => 'integer',\n\t\t\t'default'           => 10,\n\t\t\t'minimum'           => 1,\n\t\t\t'maximum'           => 100,\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_messages_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-messages/classes/class-bp-rest-sitewide-notices-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Sitewide_Notices_Endpoint class\n *\n * @package BuddyPress\n * @since 9.0.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Sitewide Notices endpoints.\n *\n * @since 9.0.0\n */\nclass BP_REST_Sitewide_Notices_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 9.0.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Messages_Sitewide_Notices_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = 'sitewide-notices';\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 9.0.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the Sitewide notice.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::DELETABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/dismiss',\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'dismiss_notice' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'dismiss_notice_permissions_check' ), // Anyone who can get items can dismiss them.\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve sitewide notices.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$context = $request->get_param( 'context' );\n\n\t\tif ( 'edit' === $context && bp_current_user_can( 'bp_moderate' ) ) {\n\n\t\t\t$args = array(\n\t\t\t\t'pag_page' => $request->get_param( 'page' ),\n\t\t\t\t'pag_num'  => $request->get_param( 'per_page' ),\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * Filter the query arguments for the request.\n\t\t\t *\n\t\t\t * @since 9.0.0\n\t\t\t *\n\t\t\t * @param array           $args    Key value array of query var to query value.\n\t\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t\t */\n\t\t\t$args = apply_filters( 'bp_rest_sitewide_notices_get_items_query_args', $args, $request );\n\n\t\t\t$notices = BP_Messages_Notice::get_notices( $args );\n\n\t\t\t$retval = array();\n\t\t\tforeach ( (array) $notices as $notice ) {\n\t\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t\t$this->prepare_item_for_response( $notice, $request )\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t$response = rest_ensure_response( $retval );\n\t\t\t$response = bp_rest_response_add_total_headers( $response, BP_Messages_Notice::get_total_notice_count(), $args['pag_num'] );\n\n\t\t} else {\n\t\t\t// Ordinary users, or Admins who aren't currently managing notices, only get the most recent notice.\n\t\t\t$retval  = array();\n\t\t\t$notice  = BP_Messages_Notice::get_active();\n\t\t\t$notices = array();\n\t\t\tif ( ! empty( $notice ) ) {\n\t\t\t\t// Make sure the user hasn't already dismissed it.\n\t\t\t\t$closed_notices = bp_get_user_meta( bp_loggedin_user_id(), 'closed_notices', true );\n\t\t\t\tif ( empty( $closed_notices ) ) {\n\t\t\t\t\t$closed_notices = array();\n\t\t\t\t}\n\t\t\t\tif ( $notice->id && is_array( $closed_notices ) && ! in_array( $notice->id, $closed_notices, true ) ) {\n\t\t\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t\t\t$this->prepare_item_for_response( $notice, $request )\n\t\t\t\t\t);\n\t\t\t\t\t// Add the item to the notices array used in the filter.\n\t\t\t\t\t$notices[] = $notice;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$response = rest_ensure_response( $retval );\n\t\t\t// The count is either 0 or 1, since there can only be one active notice at a time.\n\t\t\t$response = bp_rest_response_add_total_headers( $response, count( $retval ), 1 );\n\t\t}\n\n\t\t/**\n\t\t * Fires after notices are fetched via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param array            $notices  Fetched notices.\n\t\t * @param WP_REST_Response $response The response data.\n\t\t * @param WP_REST_Request  $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_sitewide_notices_get_items', $notices, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request is allowed to get notices.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_Error|bool\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$context = $request->get_param( 'context' );\n\t\t$retval  = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to see the notices.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\tif ( 'view' === $context ) {\n\t\t\t\t$retval = true;\n\t\t\t} elseif ( 'edit' === $context ) {\n\t\t\t\t$retval = bp_current_user_can( 'bp_moderate' );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the messages `get_items` permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Get a single notice by ID.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_item( $request ) {\n\t\t$notice = $this->get_notice_object( $request->get_param( 'id' ) );\n\n\t\t$retval   = $this->prepare_item_for_response( $notice, $request );\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a sitewide notice is fetched via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param BP_Messages_Notice $notice  Notice object.\n\t\t * @param WP_REST_Response   $retval  The response data.\n\t\t * @param WP_REST_Request    $request The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_sitewide_notices_get_item', $notice, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request is allowed to get a sitewide notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_Error|bool\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$error  = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to see this notice.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\t\t$retval = $error;\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$notice = $this->get_notice_object( $request->get_param( 'id' ) );\n\t\t\tif ( empty( $notice->id ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Sorry, this notice does not exist.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t// Non-admin users can only see the active notice.\n\t\t\t\t$is_active = isset( $notice->is_active ) ? $notice->is_active : false;\n\t\t\t\tif ( ! $is_active ) {\n\t\t\t\t\t$retval = $error;\n\t\t\t\t} else {\n\t\t\t\t\t$retval = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the sitewide notices `get_item` permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_get_item_permissions_check', $retval, $request, $notice );\n\t}\n\n\t/**\n\t * Create a sitewide notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$subject = $request->get_param( 'subject' );\n\t\t$message = $request->get_param( 'message' );\n\t\t$success = messages_send_notice( $subject, $message );\n\n\t\tif ( ! $success ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_create_sitewide_notice',\n\t\t\t\t__( 'Cannot create new sitewide notice.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// The notice we just created will be active.\n\t\t$notice        = BP_Messages_Notice::get_active();\n\t\t$fields_update = $this->update_additional_fields_for_object( $notice, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval   = $this->prepare_item_for_response( $notice, $request );\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a sitewide notice is created via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param BP_Messages_Notice $notice   Notice object.\n\t\t * @param WP_REST_Response   $response The response data.\n\t\t * @param WP_REST_Request    $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_sitewide_notices_create_item', $notice, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to create a notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_Error|bool\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = $this->manage_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the sitewide notices `create_item` permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update a notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Check the notice exists.\n\t\t$notice = $this->get_notice_object( $request->get_param( 'id' ) );\n\t\tif ( ! $notice->id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Sorry, this notice does not exist.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Update the notice.\n\t\t$updated_notice = $this->prepare_item_for_database( $request );\n\t\tif ( ! $updated_notice->save() ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_sitewide_notices_update_failed',\n\t\t\t\t__( 'There was an error trying to update the notice.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$fields_update = $this->update_additional_fields_for_object( $updated_notice, $request );\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval   = $this->prepare_item_for_response( $updated_notice, $request );\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a sitewide notice is updated via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param BP_Messages_Notice $updated_notice The notice object.\n\t\t * @param WP_REST_Response   $response       The response data.\n\t\t * @param WP_REST_Request    $request        The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_sitewide_notices_update_item', $updated_notice, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_Error|bool\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = $this->manage_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the sitewide notices `update_item` permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Dismisses the currently active notice for the current user.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function dismiss_notice( $request ) {\n\t\t// Mark the active notice as closed.\n\t\t$notice = BP_Messages_Notice::get_active();\n\n\t\tif ( ! $notice->id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Sorry, this notice does not exist.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get Previous active notice.\n\t\t$previous = $this->prepare_item_for_response( $notice, $request );\n\n\t\t// Dismiss the active notice for the current user.\n\t\t$dismissed = bp_messages_dismiss_sitewide_notice();\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'dismissed' => $dismissed,\n\t\t\t\t'previous'  => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a sitewide notice is dismissed via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param BP_Messages_Notice  $notice   Notice object.\n\t\t * @param WP_REST_Response    $response The response data.\n\t\t * @param WP_REST_Request     $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_sitewide_notices_dismiss_notice', $notice, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to dismiss the current notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_Error|bool\n\t */\n\tpublic function dismiss_notice_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to dismiss notices.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the sitewide notices `dismiss_notice` permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_dismiss_notice_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete a sitewide notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the notice before it's deleted.\n\t\t$notice = $this->get_notice_object( $request->get_param( 'id' ) );\n\t\tif ( ! $notice->id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Sorry, this notice does not exist.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$previous = $this->prepare_item_for_response( $notice, $request );\n\n\t\t// Delete a sitewide notice.\n\t\tif ( ! $notice->delete() ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_sitewide_notice_delete_failed',\n\t\t\t\t__( 'There was an error trying to delete a notice.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a sitewide notice is deleted via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param BP_Messages_Notice $notice  Notice object.\n\t\t * @param WP_REST_Response   $response The response data.\n\t\t * @param WP_REST_Request    $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_sitewide_notices_delete_item', $notice, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to generally manage a notice.\n\t * Granular filters are provided in the edit_, create_, and delete_\n\t * permissions checks.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_Error|bool\n\t */\n\tpublic function manage_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the notice `manage_item` permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_manage_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a notice.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_Error|bool\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->manage_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the sitewide notices `create_item` permissions check.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param bool|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param BP_Messages_Notice $notice Notice object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $notice ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $notice->id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param array              $links   The prepared links of the REST response.\n\t\t * @param BP_Messages_Notice $notice  Notice object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_prepare_links', $links, $notice );\n\t}\n\n\t/**\n\t * Prepares sitewide notice data for return as an object.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param BP_Messages_Notice $notice  The notice object.\n\t * @param WP_REST_Request    $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $notice, $request ) {\n\t\t$data = array(\n\t\t\t'id'        => (int) $notice->id,\n\t\t\t'subject'   => array(\n\t\t\t\t'raw'      => $notice->subject,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_message_notice_subject', wp_staticize_emoji( $notice->subject ) ),\n\t\t\t),\n\t\t\t'message'   => array(\n\t\t\t\t'raw'      => $notice->message,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_message_notice_text', wp_staticize_emoji( $notice->message ) ),\n\t\t\t),\n\t\t\t'date'      => bp_rest_prepare_date_response( $notice->date_sent, get_date_from_gmt( $notice->date_sent ) ),\n\t\t\t'date_gmt'  => bp_rest_prepare_date_response( $notice->date_sent ),\n\t\t\t'is_active' => (bool) $notice->is_active,\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $notice ) );\n\n\t\t/**\n\t\t * Filter sitewide notice data returned from the API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param WP_REST_Response   $response Response generated by the request.\n\t\t * @param WP_REST_Request    $request  Request used to generate the response.\n\t\t * @param BP_Messages_Notice $notice   The notice object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_prepare_value', $response, $request, $notice );\n\t}\n\n\t/**\n\t * Get sitewide notice object.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param int $id Notice ID.\n\t * @return BP_Messages_Notice\n\t */\n\tpublic function get_notice_object( $id ) {\n\t\t$notice = new BP_Messages_Notice( $id );\n\n\t\tif ( ! $notice->date_sent ) {\n\t\t\t$notice->id = null;\n\t\t}\n\n\t\treturn $notice;\n\t}\n\n\t/**\n\t * Select the item schema arguments needed for the CREATABLE, EDITABLE and DELETABLE methods.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$key                       = 'get_item';\n\t\t$args                      = WP_REST_Controller::get_endpoint_args_for_item_schema( $method );\n\t\t$args['id']['description'] = __( 'ID of the sitewide notice.', 'buddypress' );\n\n\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\n\t\t\t// Edit the Sitewide Notice ID description and default properties.\n\t\t\t$args['id']['description'] = __( 'ID of the sitewide notice. Required when editing an existing notice.', 'buddypress' );\n\t\t\t$args['id']['default']     = 0;\n\n\t\t\t// Edit subject's properties.\n\t\t\t$args['subject']['type']        = 'string';\n\t\t\t$args['subject']['default']     = false;\n\t\t\t$args['subject']['description'] = __( 'Subject of the sitewide notice.', 'buddypress' );\n\n\t\t\t// Edit message's properties.\n\t\t\t$args['message']['type']        = 'string';\n\t\t\t$args['message']['description'] = __( 'Content of the sitewide notice.', 'buddypress' );\n\n\t\t} else {\n\t\t\tunset( $args['subject'], $args['message'] );\n\t\t\t$args['id']['required'] = true;\n\n\t\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t\t$key = 'update_item';\n\n\t\t\t\t// Edit the Sitewide Notice ID description and default properties.\n\t\t\t\t$args['id']['description'] = __( 'ID of the sitewide notice to update. Required when editing an existing notice.', 'buddypress' );\n\t\t\t}\n\n\t\t\tif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t\t$key = 'delete_item';\n\n\t\t\t\t// Edit the Sitewide Notice ID description and default properties.\n\t\t\t\t$args['id']['description'] = __( 'ID of the sitewide notice to delete. Required when deleting an existing notice.', 'buddypress' );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param array $args Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_sitewide_notices_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the message schema, conforming to JSON Schema.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_sitewide_notices',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the sitewide notice.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'subject'   => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Subject of the sitewide notice.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Title of the sitewide notice, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t\t'default'     => false,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Title of the sitewide notice, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t\t'default'     => false,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'message'   => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Content of the sitewide notice.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the sitewide notice, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the sitewide notice, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'date'      => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date of the sitewide notice, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'date_gmt'  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date of the sitewide notice, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'is_active' => array(\n\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether this notice is active or not.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the notice schema.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for sitewide notices collections.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_collection_params', $params );\n\t}\n\n\t/**\n\t * Prepare a notice for creation or update.\n\t *\n\t * @since 9.0.0\n\t *\n\t * @param WP_REST_Request $request Request object.\n\t * @return BP_Messages_Notice|WP_Error Object or WP_Error.\n\t */\n\tprotected function prepare_item_for_database( $request ) {\n\t\t$schema        = $this->get_item_schema();\n\t\t$notice_id     = $request->get_param( 'id' );\n\t\t$prepared_item = $this->get_notice_object( $notice_id );\n\n\t\t// Notice ID.\n\t\tif ( ! empty( $schema['properties']['id'] ) && ! empty( $prepared_item->id ) ) {\n\t\t\t$prepared_item->id = $prepared_item->id;\n\t\t}\n\n\t\t// Notice subject.\n\t\t$subject = $request->get_param( 'subject' );\n\t\tif ( ! empty( $schema['properties']['subject'] ) && $subject ) {\n\t\t\tif ( is_string( $subject ) ) {\n\t\t\t\t$prepared_item->subject = $subject;\n\t\t\t} elseif ( isset( $subject['raw'] ) ) {\n\t\t\t\t$prepared_item->subject = $subject['raw'];\n\t\t\t}\n\t\t}\n\n\t\t// Notice message.\n\t\t$message = $request->get_param( 'message' );\n\t\tif ( ! empty( $schema['properties']['message'] ) && $message ) {\n\t\t\tif ( is_string( $message ) ) {\n\t\t\t\t$prepared_item->message = $message;\n\t\t\t} elseif ( isset( $message['raw'] ) ) {\n\t\t\t\t$prepared_item->message = $message['raw'];\n\t\t\t}\n\t\t}\n\n\t\t// Date_sent is set at creation, so nothing to do.\n\n\t\t// Is active.\n\t\t$is_active = $request->get_param( 'is_active' );\n\t\tif ( ! empty( $schema['properties']['is_active'] ) && ! is_null( $is_active ) ) {\n\t\t\t// The method get_param() returns a string, so we must convert to an integer.\n\t\t\t$prepared_item->is_active = absint( $is_active );\n\t\t}\n\n\t\t/**\n\t\t * Filters a notice before it is updated via the REST API.\n\t\t *\n\t\t * @since 9.0.0\n\t\t *\n\t\t * @param BP_Messages_Notice $prepared_item A BP_Messages_Notice object prepared for inserting or updating the database.\n\t\t * @param WP_REST_Request $request Request object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_sitewide_notices_pre_update_value', $prepared_item, $request );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-notifications/classes/class-bp-rest-notifications-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_Notifications_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * Notifications endpoints.\n *\n * @since 0.1.0\n */\nclass BP_REST_Notifications_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_Notifications_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = buddypress()->notifications->id;\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the notification.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'context' => $this->get_context_param(\n\t\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t\t'default' => 'view',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve notifications.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'user_id'           => $request->get_param( 'user_id' ),\n\t\t\t'user_ids'          => $request->get_param( 'user_ids' ),\n\t\t\t'item_id'           => $request->get_param( 'item_id' ),\n\t\t\t'secondary_item_id' => $request->get_param( 'secondary_item_id' ),\n\t\t\t'component_name'    => $request->get_param( 'component_name' ),\n\t\t\t'component_action'  => $request->get_param( 'component_action' ),\n\t\t\t'order_by'          => $request->get_param( 'order_by' ),\n\t\t\t'sort_order'        => strtoupper( $request->get_param( 'sort_order' ) ),\n\t\t\t'is_new'            => $request->get_param( 'is_new' ),\n\t\t\t'page'              => $request->get_param( 'page' ),\n\t\t\t'per_page'          => $request->get_param( 'per_page' ),\n\t\t);\n\n\t\tif ( empty( $request->get_param( 'component_action' ) ) ) {\n\t\t\t$args['component_action'] = false;\n\t\t}\n\n\t\tif ( ! empty( $args['user_ids'] ) ) {\n\t\t\t$args['user_id'] = $args['user_ids'];\n\t\t} elseif ( empty( $args['user_id'] ) ) {\n\t\t\t\t$args['user_id'] = bp_loggedin_user_id();\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'component_name' ) ) ) {\n\t\t\t$args['component_name'] = false;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_notifications_get_items_query_args', $args, $request );\n\n\t\t// Actually, query it.\n\t\t$notifications = BP_Notifications_Notification::get( $args );\n\n\t\t$retval = array();\n\t\tforeach ( $notifications as $notification ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $notification, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after notifications are fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $notifications Fetched notifications.\n\t\t * @param WP_REST_Response $response      The response data.\n\t\t * @param WP_REST_Request  $request       The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_notifications_get_items', $notifications, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to the notifications.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to see the notifications.', 'buddypress' ),\n\t\t\tarray( 'status' => rest_authorization_required_code() )\n\t\t);\n\n\t\tif ( ( is_user_logged_in() && bp_loggedin_user_id() === $request->get_param( 'user_id' ) && ! $request->get_param( 'user_ids' ) ) || $this->can_see() ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the notifications `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve a notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_item( $request ) {\n\t\t$notification = $this->get_notification_object( $request );\n\t\t$retval       = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $notification, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a notification is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Notifications_Notification $notification Fetched notification.\n\t\t * @param WP_REST_Response              $response     The response data.\n\t\t * @param WP_REST_Request               $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_notifications_get_item', $notification, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get information about a specific notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to see the notification.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$notification = $this->get_notification_object( $request );\n\n\t\t\tif ( empty( $notification ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_notification_invalid_id',\n\t\t\t\t\t__( 'Invalid notification ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( $this->can_see( $notification->id ) ) {\n\t\t\t\t$retval = true;\n\t\t\t} else {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t\t__( 'Sorry, you cannot view this notification.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the notifications `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Create a notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$notification_id = bp_notifications_add_notification( $this->prepare_item_for_database( $request ) );\n\n\t\tif ( ! is_numeric( $notification_id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_create_notification',\n\t\t\t\t__( 'Cannot create new notification.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$notification  = $this->get_notification_object( $notification_id );\n\t\t$fields_update = $this->update_additional_fields_for_object( $notification, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $notification, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a notification is created via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Notifications_Notification  $notification The created notification.\n\t\t * @param WP_REST_Response               $response     The response data.\n\t\t * @param WP_REST_Request                $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_notifications_create_item', $notification, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Checks if a given request has access to create a notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = $this->get_items_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the notifications `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update a notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$notification = $this->get_notification_object( $request );\n\t\t$is_new       = $request->get_param( 'is_new' );\n\n\t\tif ( $is_new === $notification->is_new ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_notification_status',\n\t\t\t\t__( 'Notification is already with the status you are trying to update into.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$updated = BP_Notifications_Notification::update(\n\t\t\tarray( 'is_new' => $is_new ),\n\t\t\tarray( 'id' => $notification->id )\n\t\t);\n\n\t\tif ( ! (bool) $updated ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_notification',\n\t\t\t\t__( 'Cannot update the status of this notification.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Make sure to update the status of the notification.\n\t\t$notification = $this->prepare_item_for_database( $request );\n\n\t\t// Update additional fields.\n\t\t$fields_update = $this->update_additional_fields_for_object( $notification, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $notification, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a notification is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Notifications_Notification $notification The updated notification.\n\t\t * @param WP_REST_Response              $response     The response data.\n\t\t * @param WP_REST_Request               $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_notifications_update_item', $notification, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error|bool\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the notifications `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete a notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the notification before it's deleted.\n\t\t$notification = $this->get_notification_object( $request );\n\t\t$previous     = $this->prepare_item_for_response( $notification, $request );\n\n\t\tif ( ! BP_Notifications_Notification::delete( array( 'id' => $notification->id ) ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_notification_invalid_id',\n\t\t\t\t__( 'Invalid notification ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a notification is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_Notifications_Notification $notification The deleted notification.\n\t\t * @param WP_REST_Response              $response     The response data.\n\t\t * @param WP_REST_Request               $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_notifications_delete_item', $notification, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a notification.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request $request Full details about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->get_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the notifications `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares notification data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Notifications_Notification $notification Notification object.\n\t * @param WP_REST_Request               $request      Full details about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $notification, $request ) {\n\t\t$data = array(\n\t\t\t'id'                => (int) $notification->id,\n\t\t\t'user_id'           => (int) $notification->user_id,\n\t\t\t'item_id'           => (int) $notification->item_id,\n\t\t\t'secondary_item_id' => (int) $notification->secondary_item_id,\n\t\t\t'component'         => $notification->component_name,\n\t\t\t'action'            => $notification->component_action,\n\t\t\t'date'              => bp_rest_prepare_date_response( $notification->date_notified, get_date_from_gmt( $notification->date_notified ) ),\n\t\t\t'date_gmt'          => bp_rest_prepare_date_response( $notification->date_notified ),\n\t\t\t'is_new'            => (int) $notification->is_new,\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $notification ) );\n\n\t\t/**\n\t\t * Filter a notification value returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response              $response     The response data.\n\t\t * @param WP_REST_Request               $request      Request used to generate the response.\n\t\t * @param BP_Notifications_Notification $notification Notification object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_prepare_value', $response, $request, $notification );\n\t}\n\n\t/**\n\t * Prepare a notification for create or update.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return stdClass\n\t */\n\tprotected function prepare_item_for_database( $request ) {\n\t\t$prepared_notification = new stdClass();\n\t\t$schema                = $this->get_item_schema();\n\t\t$notification          = $this->get_notification_object( $request );\n\n\t\tif ( ! empty( $schema['properties']['id'] ) && ! empty( $notification->id ) ) {\n\t\t\t$prepared_notification->id = $notification->id;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['user_id'] ) && ! empty( $request->get_param( 'user_id' ) ) ) {\n\t\t\t$prepared_notification->user_id = (int) $request->get_param( 'user_id' );\n\t\t} elseif ( isset( $notification->user_id ) ) {\n\t\t\t$prepared_notification->user_id = $notification->user_id;\n\t\t} else {\n\t\t\t$prepared_notification->user_id = bp_loggedin_user_id();\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['item_id'] ) && ! empty( $request->get_param( 'item_id' ) ) ) {\n\t\t\t$prepared_notification->item_id = $request->get_param( 'item_id' );\n\t\t} elseif ( isset( $notification->item_id ) ) {\n\t\t\t$prepared_notification->item_id = $notification->item_id;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['secondary_item_id'] ) && ! empty( $request->get_param( 'secondary_item_id' ) ) ) {\n\t\t\t$prepared_notification->secondary_item_id = $request->get_param( 'secondary_item_id' );\n\t\t} elseif ( isset( $notification->secondary_item_id ) ) {\n\t\t\t$prepared_notification->secondary_item_id = $notification->secondary_item_id;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['component'] ) && ! empty( $request->get_param( 'component' ) ) ) {\n\t\t\t$prepared_notification->component_name = $request->get_param( 'component' );\n\t\t} elseif ( isset( $notification->component_name ) ) {\n\t\t\t$prepared_notification->component_name = $notification->component_name;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['action'] ) && ! empty( $request->get_param( 'action' ) ) ) {\n\t\t\t$prepared_notification->component_action = $request->get_param( 'action' );\n\t\t} elseif ( isset( $notification->component_action ) ) {\n\t\t\t$prepared_notification->component_action = $notification->component_action;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['is_new'] ) && ! empty( $request->get_param( 'is_new' ) ) ) {\n\t\t\t$prepared_notification->is_new = $request->get_param( 'is_new' );\n\t\t} elseif ( isset( $notification->is_new ) ) {\n\t\t\t$prepared_notification->is_new = $notification->is_new;\n\t\t}\n\n\t\tif ( ! empty( $schema['properties']['date'] ) && ! empty( $request->get_param( 'date' ) ) ) {\n\t\t\t$prepared_notification->date_notified = $request->get_param( 'date' );\n\t\t} elseif ( isset( $notification->date_notified ) ) {\n\t\t\t$prepared_notification->date_notified = $notification->date_notified;\n\t\t}\n\n\t\t/**\n\t\t * Filters a notification before it is inserted or updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param stdClass        $prepared_notification An object prepared for inserting or updating the database.\n\t\t * @param WP_REST_Request $request               Full details about the request.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_pre_insert_value', $prepared_notification, $request );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_Notifications_Notification $notification Notification item.\n\t * @return array\n\t */\n\tprotected function prepare_links( $notification ) {\n\t\t$base = sprintf( '/%1$s/%2$s/', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $notification->id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\t// Embed User.\n\t\tif ( ! empty( $notification->user_id ) ) {\n\t\t\t$links['user'] = array(\n\t\t\t\t'embeddable' => true,\n\t\t\t\t'href'       => bp_rest_get_object_url( absint( $notification->user_id ), 'members' ),\n\t\t\t);\n\t\t}\n\n\t\t// Embed Activity.\n\t\tif ( bp_is_active( 'activity' ) && buddypress()->activity->id === $notification->component_name && ! empty( $notification->item_id ) ) {\n\t\t\t$links[ buddypress()->activity->id ] = array(\n\t\t\t\t'embeddable' => true,\n\t\t\t\t'href'       => rest_url(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t'/%1$s/%2$s/%3$d',\n\t\t\t\t\t\t$this->namespace,\n\t\t\t\t\t\tbuddypress()->activity->id,\n\t\t\t\t\t\tabsint( $notification->item_id )\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Embed Group.\n\t\tif ( bp_is_active( 'groups' ) && buddypress()->groups->id === $notification->component_name && ! empty( $notification->item_id ) ) {\n\t\t\t$links['group'] = array(\n\t\t\t\t'embeddable' => true,\n\t\t\t\t'href'       => rest_url(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t'/%1$s/%2$s/%3$d',\n\t\t\t\t\t\t$this->namespace,\n\t\t\t\t\t\tbuddypress()->groups->id,\n\t\t\t\t\t\tabsint( $notification->item_id )\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t// Embed Blog.\n\t\tif ( is_multisite() && bp_is_active( 'blogs' ) && buddypress()->blogs->id === $notification->component_name && ! empty( $notification->item_id ) ) {\n\t\t\t$links['blog'] = array(\n\t\t\t\t'embeddable' => true,\n\t\t\t\t'href'       => rest_url(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t'/%1$s/%2$s/%3$d',\n\t\t\t\t\t\t$this->namespace,\n\t\t\t\t\t\tbuddypress()->blogs->id,\n\t\t\t\t\t\tabsint( $notification->item_id )\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array                         $links        The prepared links of the REST response.\n\t\t * @param BP_Notifications_Notification $notification Notification object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_prepare_links', $links, $notification );\n\t}\n\n\t/**\n\t * Can this user see the notification?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $notification_id Notification ID.\n\t * @return bool\n\t */\n\tprotected function can_see( $notification_id = 0 ) {\n\n\t\t// Check notification access.\n\t\tif ( ! empty( $notification_id ) && (bool) BP_Notifications_Notification::check_access( bp_loggedin_user_id(), $notification_id ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Moderators as well.\n\t\treturn bp_current_user_can( 'bp_moderate' );\n\t}\n\n\t/**\n\t * Get a notification object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  int|WP_REST_Request $request Full details about the request or an integer.\n\t * @return BP_Notifications_Notification|string A notification object|Empty string.\n\t */\n\tpublic function get_notification_object( $request ) {\n\t\t$notification_id = is_numeric( $request ) ? $request : $request->get_param( 'id' );\n\t\t$notification    = bp_notifications_get_notification( absint( $notification_id ) );\n\n\t\t// Inexistent notification objects return the id being checked, so confirm another field is present.\n\t\tif ( empty( $notification->id ) || is_null( $notification->item_id ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn $notification;\n\t}\n\n\t/**\n\t * Select the item schema arguments needed for the EDITABLE method.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key = 'update_item';\n\n\t\t\t// Only switching the is_new property can be achieved.\n\t\t\t$args                      = array_intersect_key( $args, array( 'is_new' => true ) );\n\t\t\t$args['is_new']['default'] = 0;\n\t\t} elseif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t$key = 'create_item';\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_notifications_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the notification schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_notifications',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the notification.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'user_id'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the user the notification is addressed to.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'default'     => bp_loggedin_user_id(),\n\t\t\t\t\t),\n\t\t\t\t\t'item_id'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the item associated with the notification.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'secondary_item_id' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the secondary item associated with the notification.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'component'         => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The name of the BuddyPress component the notification relates to.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'action'            => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The name of the component\\'s action the notification is about.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t),\n\t\t\t\t\t'date'              => array(\n\t\t\t\t\t\t'description' => __( 'The date the notification was created, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t),\n\t\t\t\t\t'date_gmt'          => array(\n\t\t\t\t\t\t'description' => __( 'The date the notification was created, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t),\n\t\t\t\t\t'is_new'            => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether it\\'s a new notification or not.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t\t'default'     => 1,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the notification schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notification_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for the notifications collections.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t// Remove the search argument.\n\t\tunset( $params['search'] );\n\n\t\t$params['order_by'] = array(\n\t\t\t'description'       => __( 'Name of the field to order according to.', 'buddypress' ),\n\t\t\t'default'           => 'id',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'id', 'date_notified', 'item_id', 'secondary_item_id', 'component_name', 'component_action' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['sort_order'] = array(\n\t\t\t'description'       => __( 'Order sort attribute ascending or descending.', 'buddypress' ),\n\t\t\t'default'           => 'ASC',\n\t\t\t'type'              => 'string',\n\t\t\t'enum'              => array( 'ASC', 'DESC' ),\n\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['component_name'] = array(\n\t\t\t'description'       => __( 'Limit result set to notifications associated with a specific component', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['component_action'] = array(\n\t\t\t'description'       => __( 'Limit result set to notifications associated with a specific component\\'s action name.', 'buddypress' ),\n\t\t\t'default'           => '',\n\t\t\t'type'              => 'string',\n\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to notifications addressed to a specific user.', 'buddypress' ),\n\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_ids'] = array(\n\t\t\t'description'       => __( 'Limit result set to notifications addressed to a list of specific users.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['item_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to notifications associated with a specific item ID.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['secondary_item_id'] = array(\n\t\t\t'description'       => __( 'Limit result set to notifications associated with a specific secondary item ID.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['is_new'] = array(\n\t\t\t'description'       => __( 'Limit result set to items from specific states.', 'buddypress' ),\n\t\t\t'default'           => true,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_notifications_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-xprofile/classes/class-bp-rest-xprofile-data-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_XProfile_Data_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * XProfile Data endpoints.\n *\n * Use /xprofile/{field_id}/data/{user_id}\n *\n * @since 0.1.0\n */\nclass BP_REST_XProfile_Data_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * XProfile Fields Class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_XProfile_Fields_Endpoint\n\t */\n\tprotected $fields_endpoint;\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_XProfile_Data_REST_Controller' );\n\n\t\t$this->namespace       = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base       = buddypress()->profile->id;\n\t\t$this->fields_endpoint = new BP_REST_XProfile_Fields_Endpoint();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<field_id>[\\d]+)/data/(?P<user_id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'field_id' => array(\n\t\t\t\t\t\t'description' => __( 'The ID of the field the data is from.', 'buddypress' ),\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'user_id'  => array(\n\t\t\t\t\t\t'description' => __( 'The ID of user the field data is from.', 'buddypress' ),\n\t\t\t\t\t\t'required'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'value' => array(\n\t\t\t\t\t\t\t'description'       => __( 'The value(s) (comma separated list of values needs to be used in case of multiple values) for the field data.', 'buddypress' ),\n\t\t\t\t\t\t\t'required'          => true,\n\t\t\t\t\t\t\t'type'              => 'string',\n\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve single XProfile field data.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_item( $request ) {\n\t\t// Get Field data.\n\t\t$field_data = $this->get_xprofile_field_data_object( $request->get_param( 'field_id' ), $request->get_param( 'user_id' ) );\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field_data, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires before a XProfile data is retrieved via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_ProfileData $field_data The field data object.\n\t\t * @param WP_REST_Response      $response  The response data.\n\t\t * @param WP_REST_Request       $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_data_get_item', $field_data, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get users's data.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you cannot view the extended profile information.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'xprofile' ) ) ) {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_hidden_profile_field',\n\t\t\t\t__( 'Sorry, the profile field value is not viewable for this user.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 403,\n\t\t\t\t)\n\t\t\t);\n\n\t\t\t// Check the field exists.\n\t\t\t$field = $this->get_xprofile_field_object( $request->get_param( 'field_id' ) );\n\n\t\t\tif ( empty( $field->id ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Invalid field ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t$user = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\n\t\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t\t'bp_rest_member_invalid_id',\n\t\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// Check the user can view this field value.\n\t\t\t\t\t$hidden_user_fields = bp_xprofile_get_hidden_fields_for_user( $user->ID );\n\n\t\t\t\t\tif ( ! in_array( $field->id, $hidden_user_fields, true ) ) {\n\t\t\t\t\t\t$retval = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile data `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_data_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Save XProfile data.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$field = $this->get_xprofile_field_object( $request->get_param( 'field_id' ) );\n\n\t\tif ( empty( $field->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid field ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$user  = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\t\t$value = $request->get_param( 'value' );\n\n\t\t/**\n\t\t * For field types not supporting multiple values, join values in case\n\t\t * the submitted value was not an array.\n\t\t */\n\t\tif ( false === (bool) $field->type_obj->supports_multiple_defaults ) {\n\t\t\t$value = implode( ' ', (array) $value );\n\t\t} elseif ( ! empty( $value ) && is_string( $value ) ) {\n\t\t\t$value = preg_split( '/[,]+/', $value );\n\t\t}\n\n\t\tif ( ! xprofile_set_field_data( $field->id, $user->ID, $value ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'rest_user_cannot_save_xprofile_data',\n\t\t\t\t__( 'Cannot save XProfile data.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Get field data.\n\t\t$field_data = $this->get_xprofile_field_data_object( $field->id, $user->ID );\n\n\t\t// Add additional fields.\n\t\t$fields_update = $this->update_additional_fields_for_object( $field_data, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field_data, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a XProfile data is saved via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Field       $field      The field object.\n\t\t * @param BP_XProfile_ProfileData $field_data The field data object.\n\t\t * @param WP_User                 $user       The user object.\n\t\t * @param WP_REST_Response        $response   The response data.\n\t\t * @param WP_REST_Request         $request    The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_data_save_item', $field, $field_data, $user, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to save XProfile field data.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you cannot save XProfile field data.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$user = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\n\t\t\tif ( ! $user instanceof WP_User ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Invalid member ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( $this->can_see( $user->ID ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t} else {\n\t\t\t$retval = new WP_Error(\n\t\t\t\t'bp_rest_authorization_required',\n\t\t\t\t__( 'Sorry, you need to be logged in to save XProfile data.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile data `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_data_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete user's XProfile data.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$field = $this->get_xprofile_field_object( $request->get_param( 'field_id' ) );\n\n\t\tif ( empty( $field->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid field ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$user = bp_rest_get_user( $request->get_param( 'user_id' ) );\n\n\t\t// Get the field data before it's deleted.\n\t\t$field_data = $this->get_xprofile_field_data_object( $field->id, $user->ID );\n\t\t$previous   = clone $field_data;\n\n\t\t// Set empty for the response.\n\t\t$field_data->value = '';\n\t\t$previous          = $this->prepare_item_for_response( $previous, $request );\n\n\t\tif ( false === $field_data->delete() ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_xprofile_data_cannot_delete',\n\t\t\t\t__( 'Could not delete XProfile data.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a XProfile data is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Field       $field       Deleted field object.\n\t\t * @param BP_XProfile_ProfileData $field_data  Deleted field data object.\n\t\t * @param WP_User                 $user        User object.\n\t\t * @param WP_REST_Response        $response    The response data.\n\t\t * @param WP_REST_Request         $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_data_delete_item', $field, $field_data, $user, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete users's data.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->update_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the XProfile data `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_data_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares XProfile data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  BP_XProfile_ProfileData $field_data XProfile field data object.\n\t * @param  WP_REST_Request         $request    Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $field_data, $request ) {\n\t\t$data = array(\n\t\t\t'id'               => (int) $field_data->id,\n\t\t\t'field_id'         => (int) $field_data->field_id,\n\t\t\t'user_id'          => (int) $field_data->user_id,\n\t\t\t'last_updated'     => bp_rest_prepare_date_response( $field_data->last_updated, get_date_from_gmt( $field_data->last_updated ) ),\n\t\t\t'last_updated_gmt' => bp_rest_prepare_date_response( $field_data->last_updated ),\n\t\t\t'value'            => array(\n\t\t\t\t'raw'          => $field_data->value,\n\t\t\t\t'unserialized' => $this->fields_endpoint->get_profile_field_unserialized_value( $field_data->value ),\n\t\t\t\t'rendered'     => $this->fields_endpoint->get_profile_field_rendered_value( $field_data->value, $field_data->field_id ),\n\t\t\t),\n\t\t);\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t// Add prepare links.\n\t\t$response->add_links( $this->prepare_links( $field_data ) );\n\n\t\t/**\n\t\t * Filter the XProfile data response returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response        $response   The response data.\n\t\t * @param WP_REST_Request         $request    Request used to generate the response.\n\t\t * @param BP_XProfile_ProfileData $field_data XProfile field data object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_data_prepare_value', $response, $request, $field_data );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_XProfile_ProfileData $field_data XProfile field data object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $field_data ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self' => array(\n\t\t\t\t'href' => rest_url( $base . $field_data->field_id ),\n\t\t\t),\n\t\t);\n\n\t\tif ( ! empty( $field_data->user_id ) ) {\n\t\t\t$links['user'] = array(\n\t\t\t\t'href'       => bp_rest_get_object_url( $field_data->user_id, 'members' ),\n\t\t\t\t'embeddable' => true,\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array                 $links     The prepared links of the REST response.\n\t\t * @param BP_XProfile_ProfileData $field_data XProfile field data object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_data_prepare_links', $links, $field_data );\n\t}\n\n\t/**\n\t * Get XProfile field object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $field_id Field id.\n\t * @return BP_XProfile_Field\n\t */\n\tpublic function get_xprofile_field_object( $field_id ) {\n\t\treturn $this->fields_endpoint->get_xprofile_field_object( $field_id );\n\t}\n\n\t/**\n\t * Get XProfile field data object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $field_id Field id.\n\t * @param int $user_id User id.\n\t * @return BP_XProfile_ProfileData\n\t */\n\tpublic function get_xprofile_field_data_object( $field_id, $user_id ) {\n\t\treturn new BP_XProfile_ProfileData( $field_id, $user_id );\n\t}\n\n\t/**\n\t * Can this user see the XProfile data?\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param int $field_user_id User ID of the field.\n\t * @return bool\n\t */\n\tprotected function can_see( $field_user_id ) {\n\t\treturn ( bp_current_user_can( 'bp_moderate' ) || bp_loggedin_user_id() === $field_user_id );\n\t}\n\n\t/**\n\t * Get the XProfile data schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_xprofile_data',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'               => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the profile data.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'field_id'         => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the field the data is from.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'user_id'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the user the field data is from.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'value'            => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The value of the field data.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null,\n\t\t\t\t\t\t\t'validate_callback' => null,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'          => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Value for the field, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'unserialized' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Unserialized value for the field, regular string will be casted as array.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'items'       => array(\n\t\t\t\t\t\t\t\t\t'type' => 'string',\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered'     => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML value for the field, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'last_updated'     => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the field data was last updated, in the site\\'s timezone.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t\t'last_updated_gmt' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The date the field data was last updated, as GMT.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => array( 'string', 'null' ),\n\t\t\t\t\t\t'format'      => 'date-time',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the xprofile data schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_data_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-xprofile/classes/class-bp-rest-xprofile-field-groups-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_XProfile_Field_Groups_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * XProfile Field Groups Endpoints.\n *\n * Use /xprofile/groups\n * Use /xprofile/groups/{id}\n *\n * @since 0.1.0\n */\nclass BP_REST_XProfile_Field_Groups_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * XProfile Fields Class.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @var BP_REST_XProfile_Fields_Endpoint\n\t */\n\tprotected $fields_endpoint;\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_XProfile_Field_Groups_REST_Controller' );\n\n\t\t$this->namespace       = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base       = buddypress()->profile->id . '/groups';\n\t\t$this->fields_endpoint = new BP_REST_XProfile_Fields_Endpoint();\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the group of profile fields.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Edit some properties for the CREATABLE & EDITABLE methods.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$key                         = 'update_item';\n\t\t\t$args['description']['type'] = 'string';\n\t\t\tunset( $args['description']['properties'] );\n\n\t\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t\t$key = 'create_item';\n\t\t\t\tunset( $args['group_order'] );\n\t\t\t}\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_xprofile_field_groups_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Retrieve XProfile groups.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'profile_group_id'       => $request->get_param( 'profile_group_id' ),\n\t\t\t'user_id'                => $request->get_param( 'user_id' ),\n\t\t\t'member_type'            => $request->get_param( 'member_type' ),\n\t\t\t'hide_empty_groups'      => $request->get_param( 'hide_empty_groups' ),\n\t\t\t'hide_empty_fields'      => $request->get_param( 'hide_empty_fields' ),\n\t\t\t'fetch_fields'           => $request->get_param( 'fetch_fields' ),\n\t\t\t'fetch_field_data'       => $request->get_param( 'fetch_field_data' ),\n\t\t\t'fetch_visibility_level' => $request->get_param( 'fetch_visibility_level' ),\n\t\t\t'exclude_groups'         => $request->get_param( 'exclude_groups' ),\n\t\t\t'exclude_fields'         => $request->get_param( 'exclude_fields' ),\n\t\t\t'update_meta_cache'      => $request->get_param( 'update_meta_cache' ),\n\t\t\t'signup_fields_only'     => $request->get_param( 'signup_fields_only' ),\n\t\t);\n\n\t\tif ( empty( $request->get_param( 'member_type' ) ) ) {\n\t\t\t$args['member_type'] = null;\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'exclude_fields' ) ) ) {\n\t\t\t$args['exclude_fields'] = false;\n\t\t}\n\n\t\tif ( empty( $request->get_param( 'exclude_groups' ) ) ) {\n\t\t\t$args['exclude_groups'] = false;\n\t\t}\n\n\t\t$include_groups = $request->get_param( 'include_groups' );\n\t\tif ( $include_groups && ! $args['profile_group_id'] ) {\n\t\t\t$args['profile_group_id'] = $include_groups;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_xprofile_field_groups_get_items_query_args', $args, $request );\n\n\t\t/**\n\t\t * Actually, query it.\n\t\t *\n\t\t * Let's not use `bp_xprofile_get_groups`, since `BP_XProfile_Data_Template` handles signup fields better.\n\t\t */\n\t\t$template_query = new BP_XProfile_Data_Template( $args );\n\t\t$field_groups   = (array) $template_query->groups;\n\n\t\t$retval = array();\n\t\tforeach ( $field_groups as $item ) {\n\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $item, $request )\n\t\t\t);\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a list of field groups are fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $field_groups Fetched field groups.\n\t\t * @param WP_REST_Response $response     The response data.\n\t\t * @param WP_REST_Request  $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_field_groups_get_items', $field_groups, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to XProfile field groups items.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'xprofile' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile fields groups `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the user has access to xprofile field groups.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve single XProfile field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$field_group = $this->get_xprofile_field_group_object( $request );\n\n\t\tif ( empty( $field_group->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid field group ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field_group, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a field group is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Group $field_group Fetched field group.\n\t\t * @param WP_REST_Response  $response    The response data.\n\t\t * @param WP_REST_Request   $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_field_groups_get_item', $field_group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get information about a specific field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'xprofile' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile fields groups `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Create a XProfile field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$args = array(\n\t\t\t'name'        => $request->get_param( 'name' ),\n\t\t\t'description' => $request->get_param( 'description' ),\n\t\t);\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_xprofile_field_groups_create_item_query_args', $args, $request );\n\n\t\tif ( empty( $args['name'] ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_required_param_missing',\n\t\t\t\t__( 'Required param missing.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 400,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$group_id = xprofile_insert_field_group( $args );\n\n\t\tif ( ! $group_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_create_xprofile_field_group',\n\t\t\t\t__( 'Cannot create new XProfile field group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$field_group = $this->get_xprofile_field_group_object( $group_id );\n\n\t\t// Create Additional fields.\n\t\t$fields_update = $this->update_additional_fields_for_object( $field_group, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field_group, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a XProfile field group is created via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Group $field_group Created field group object.\n\t\t * @param WP_REST_Response  $response    The response data.\n\t\t * @param WP_REST_Request   $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_field_groups_create_item', $field_group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to create a XProfile field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to view this XProfile field group.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() && bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile fields groups `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update a XProfile field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$field_group = $this->get_xprofile_field_group_object( $request );\n\n\t\tif ( empty( $field_group->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid field group ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$args = array(\n\t\t\t'field_group_id' => $field_group->id,\n\t\t\t'name'           => empty( $request->get_param( 'name' ) ) ? $field_group->name : $request->get_param( 'name' ),\n\t\t\t'description'    => empty( $request->get_param( 'description' ) ) ? $field_group->description : $request->get_param( 'description' ),\n\t\t);\n\n\t\t$group_id = xprofile_insert_field_group( $args );\n\n\t\tif ( ! $group_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_xprofile_field_group',\n\t\t\t\t__( 'Cannot update XProfile field group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Update the position if the group_order exists.\n\t\tif ( is_numeric( $request->get_param( 'group_order' ) ) ) {\n\t\t\txprofile_update_field_group_position( $group_id, $request->get_param( 'group_order' ) );\n\t\t}\n\n\t\t$field_group = $this->get_xprofile_field_group_object( $group_id );\n\n\t\t// Update Additional fields.\n\t\t$fields_update = $this->update_additional_fields_for_object( $field_group, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field_group, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a XProfile field group is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Group $field_group Updated field group object.\n\t\t * @param WP_REST_Response  $response    The response data.\n\t\t * @param WP_REST_Request   $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_field_groups_update_item', $field_group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to create a XProfile field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = $this->create_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the XProfile fields groups `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete a XProfile field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the field group before it's deleted.\n\t\t$field_group = $this->get_xprofile_field_group_object( $request );\n\n\t\tif ( empty( $field_group->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid field group ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( ! xprofile_delete_field_group( $field_group->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_xprofile_field_group_cannot_delete',\n\t\t\t\t__( 'Could not delete XProfile field group.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$previous = $this->prepare_item_for_response( $field_group, $request );\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a field group is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Group $field_group Deleted field group.\n\t\t * @param WP_REST_Response  $response    The response data.\n\t\t * @param WP_REST_Request   $request     The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_field_groups_delete_item', $field_group, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a field group.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = $this->create_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the XProfile fields groups `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares single XProfile field group data for return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_XProfile_Group $group   XProfile field group data.\n\t * @param WP_REST_Request   $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $group, $request ) {\n\t\t$data = array(\n\t\t\t'id'          => (int) $group->id,\n\t\t\t'name'        => $group->name,\n\t\t\t'description' => array(\n\t\t\t\t'raw'      => $group->description,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_the_profile_field_description', $group->description ),\n\t\t\t),\n\t\t\t'group_order' => (int) $group->group_order,\n\t\t\t'can_delete'  => (bool) $group->can_delete,\n\t\t);\n\n\t\t// If the fields have been requested, we populate them.\n\t\tif ( $request->get_param( 'fetch_fields' ) ) {\n\t\t\t$data['fields'] = array();\n\n\t\t\tforeach ( $group->fields as $field ) {\n\t\t\t\t$data['fields'][] = $this->fields_endpoint->assemble_response_data( $field, $request );\n\t\t\t}\n\t\t}\n\n\t\t$context  = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data     = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data     = $this->filter_response_by_context( $data, $context );\n\t\t$response = rest_ensure_response( $data );\n\n\t\t$response->add_links( $this->prepare_links( $group ) );\n\n\t\t/**\n\t\t * Filter the XProfile field group returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  Request used to generate the response.\n\t\t * @param BP_XProfile_Group  $group    XProfile field group.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_prepare_value', $response, $request, $group );\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_XProfile_Group $group XProfile field group.\n\t * @return array\n\t */\n\tprotected function prepare_links( $group ) {\n\t\t$base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $group->id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t);\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array             $links The prepared links of the REST response.\n\t\t * @param BP_XProfile_Group $group XProfile field group object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_prepare_links', $links, $group );\n\t}\n\n\t/**\n\t * Get XProfile field group object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full details about the request.\n\t * @return BP_XProfile_Group|string XProfile field group object.\n\t */\n\tpublic function get_xprofile_field_group_object( $request ) {\n\t\tif ( is_numeric( $request ) ) {\n\t\t\t$args = array(\n\t\t\t\t'profile_group_id' => $request,\n\t\t\t);\n\t\t} else {\n\t\t\t$args = array(\n\t\t\t\t'profile_group_id'       => (int) $request->get_param( 'id' ),\n\t\t\t\t'user_id'                => $request->get_param( 'user_id' ),\n\t\t\t\t'member_type'            => $request->get_param( 'member_type' ),\n\t\t\t\t'hide_empty_fields'      => $request->get_param( 'hide_empty_fields' ),\n\t\t\t\t'fetch_fields'           => $request->get_param( 'fetch_fields' ),\n\t\t\t\t'fetch_field_data'       => $request->get_param( 'fetch_field_data' ),\n\t\t\t\t'fetch_visibility_level' => $request->get_param( 'fetch_visibility_level' ),\n\t\t\t\t'exclude_fields'         => $request->get_param( 'exclude_fields' ),\n\t\t\t\t'update_meta_cache'      => $request->get_param( 'update_meta_cache' ),\n\t\t\t);\n\n\t\t\tif ( empty( $request->get_param( 'member_type' ) ) ) {\n\t\t\t\t$args['member_type'] = null;\n\t\t\t}\n\n\t\t\tif ( empty( $request->get_param( 'exclude_fields' ) ) ) {\n\t\t\t\t$args['exclude_fields'] = false;\n\t\t\t}\n\t\t}\n\n\t\t$field_group = current( bp_xprofile_get_groups( $args ) );\n\n\t\tif ( empty( $field_group->id ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn $field_group;\n\t}\n\n\t/**\n\t * Get the XProfile field group schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_xprofile_group',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the group of profile fields.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'name'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The name of group of profile fields.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'description' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The description of the group of profile fields.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t\t'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the group of profile fields, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the group of profile fields, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'group_order' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The order of the group of profile fields.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'can_delete'  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the group of profile fields can be deleted or not.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'fields'      => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The fields associated with this group of profile fields.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the xprofile field group schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_group_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for XProfile field groups.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t$params['profile_group_id'] = array(\n\t\t\t'description'       => __( 'ID of the field group that have fields.', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['hide_empty_groups'] = array(\n\t\t\t'description'       => __( 'Whether to hide profile groups of fields that do not have any profile fields or not.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Required if you want to load a specific user\\'s data.', 'buddypress' ),\n\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['member_type'] = array(\n\t\t\t'description'       => __( 'Limit fields by those restricted to a given member type, or array of member types. If `$user_id` is provided, the value of `$member_type` will be overridden by the member types of the provided user. The special value of \\'any\\' will return only those fields that are unrestricted by member type - i.e., those applicable to any type.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'string' ),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_member_types',\n\t\t\t'validate_callback' => 'bp_rest_validate_member_types',\n\t\t);\n\n\t\t$params['hide_empty_fields'] = array(\n\t\t\t'description'       => __( 'Whether to hide profile groups of fields that do not have any profile fields or not.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['fetch_fields'] = array(\n\t\t\t'description'       => __( 'Whether to fetch the fields for each group.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['signup_fields_only'] = array(\n\t\t\t'description'       => __( 'Whether to only return signup fields.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['fetch_field_data'] = array(\n\t\t\t'description'       => __( 'Whether to fetch data for each field. Requires a $user_id.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['fetch_visibility_level'] = array(\n\t\t\t'description'       => __( 'Whether to fetch the visibility level for each field.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['include_groups'] = array(\n\t\t\t'description'       => __( 'Ensure result set inludes specific profile field groups.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude_groups'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes specific profile field groups.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude_fields'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes specific profile fields.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'string' ),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_string_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['update_meta_cache'] = array(\n\t\t\t'description'       => __( 'Whether to pre-fetch xprofilemeta for all retrieved groups, fields, and data.', 'buddypress' ),\n\t\t\t'default'           => true,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_groups_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "includes/bp-xprofile/classes/class-bp-rest-xprofile-fields-endpoint.php",
    "content": "<?php\n/**\n * BP REST: BP_REST_XProfile_Fields_Endpoint class\n *\n * @package BuddyPress\n * @since 0.1.0\n */\n\ndefined( 'ABSPATH' ) || exit;\n\n/**\n * XProfile Fields endpoints.\n *\n * Use /xprofile/fields\n * Use /xprofile/fields/{id}\n *\n * @since 0.1.0\n */\nclass BP_REST_XProfile_Fields_Endpoint extends WP_REST_Controller {\n\n\t/**\n\t * Constructor.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function __construct() {\n\t\t_deprecated_class( __CLASS__, '15.0.0', 'BP_XProfile_Fields_REST_Controller' );\n\n\t\t$this->namespace = bp_rest_namespace() . '/' . bp_rest_version();\n\t\t$this->rest_base = buddypress()->profile->id . '/fields';\n\t}\n\n\t/**\n\t * Register the component routes.\n\t *\n\t * @since 0.1.0\n\t */\n\tpublic function register_routes() {\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base,\n\t\t\tarray(\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_items' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_items_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_collection_params(),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::CREATABLE,\n\t\t\t\t\t'callback'            => array( $this, 'create_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'create_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\n\t\tregister_rest_route(\n\t\t\t$this->namespace,\n\t\t\t'/' . $this->rest_base . '/(?P<id>[\\d]+)',\n\t\t\tarray(\n\t\t\t\t'args'   => array(\n\t\t\t\t\t'id' => array(\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the profile field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::READABLE,\n\t\t\t\t\t'callback'            => array( $this, 'get_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'get_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'user_id'          => array(\n\t\t\t\t\t\t\t'description'       => __( 'Required if you want to load a specific user\\'s data.', 'buddypress' ),\n\t\t\t\t\t\t\t'default'           => 0,\n\t\t\t\t\t\t\t'type'              => 'integer',\n\t\t\t\t\t\t\t'sanitize_callback' => 'absint',\n\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'fetch_field_data' => array(\n\t\t\t\t\t\t\t'description'       => __( 'Whether to fetch data for the field. Requires a $user_id.', 'buddypress' ),\n\t\t\t\t\t\t\t'default'           => false,\n\t\t\t\t\t\t\t'type'              => 'boolean',\n\t\t\t\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::EDITABLE,\n\t\t\t\t\t'callback'            => array( $this, 'update_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'update_item_permissions_check' ),\n\t\t\t\t\t'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'methods'             => WP_REST_Server::DELETABLE,\n\t\t\t\t\t'callback'            => array( $this, 'delete_item' ),\n\t\t\t\t\t'permission_callback' => array( $this, 'delete_item_permissions_check' ),\n\t\t\t\t\t'args'                => array(\n\t\t\t\t\t\t'delete_data' => array(\n\t\t\t\t\t\t\t'description'       => __( 'Required if you want to delete users data for the field.', 'buddypress' ),\n\t\t\t\t\t\t\t'default'           => false,\n\t\t\t\t\t\t\t'type'              => 'boolean',\n\t\t\t\t\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t\t\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t'schema' => array( $this, 'get_item_schema' ),\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve XProfile fields.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function get_items( $request ) {\n\t\t$args = array(\n\t\t\t'profile_group_id'       => $request->get_param( 'profile_group_id' ),\n\t\t\t'user_id'                => $request->get_param( 'user_id' ),\n\t\t\t'member_type'            => $request->get_param( 'member_type' ),\n\t\t\t'hide_empty_groups'      => $request->get_param( 'hide_empty_groups' ),\n\t\t\t'hide_empty_fields'      => $request->get_param( 'hide_empty_fields' ),\n\t\t\t'fetch_field_data'       => $request->get_param( 'fetch_field_data' ),\n\t\t\t'fetch_visibility_level' => $request->get_param( 'fetch_visibility_level' ),\n\t\t\t'exclude_groups'         => $request->get_param( 'exclude_groups' ),\n\t\t\t'exclude_fields'         => $request->get_param( 'exclude_fields' ),\n\t\t\t'update_meta_cache'      => $request->get_param( 'update_meta_cache' ),\n\t\t\t'signup_fields_only'     => $request->get_param( 'signup_fields_only' ),\n\t\t\t'fetch_fields'           => true,\n\t\t);\n\n\t\tif ( empty( $request->get_param( 'member_type' ) ) ) {\n\t\t\t$args['member_type'] = false;\n\t\t}\n\n\t\t$include_groups = $request->get_param( 'include_groups' );\n\t\tif ( $include_groups && ! $args['profile_group_id'] ) {\n\t\t\t$args['profile_group_id'] = $include_groups;\n\t\t}\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_xprofile_fields_get_items_query_args', $args, $request );\n\n\t\t/**\n\t\t * Actually, query it.\n\t\t *\n\t\t * Let's not use `bp_xprofile_get_groups`, since `BP_XProfile_Data_Template` handles signup fields better.\n\t\t */\n\t\t$template_query = new BP_XProfile_Data_Template( $args );\n\t\t$field_groups   = (array) $template_query->groups;\n\n\t\t$retval = array();\n\t\tforeach ( $field_groups as $group ) {\n\t\t\tforeach ( $group->fields as $field ) {\n\t\t\t\t$retval[] = $this->prepare_response_for_collection(\n\t\t\t\t\t$this->prepare_item_for_response( $field, $request )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a list of XProfile group fields are fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array            $field_groups Fetched field groups.\n\t\t * @param WP_REST_Response $response     The response data.\n\t\t * @param WP_REST_Request  $request      The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_fields_get_items', $field_groups, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to XProfile fields.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_items_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'xprofile' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile fields `get_items` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the user has access to xprofile fields.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_get_items_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Retrieve single XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function get_item( $request ) {\n\t\t$field = $this->get_xprofile_field_object( $request );\n\n\t\tif ( empty( $field->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid field ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif ( ! empty( $request->get_param( 'user_id' ) ) ) {\n\t\t\t$field->data = new stdClass();\n\n\t\t\t// Ensure that the requester is allowed to see this field.\n\t\t\t$hidden_user_fields = bp_xprofile_get_hidden_fields_for_user( $request->get_param( 'user_id' ) );\n\n\t\t\tif ( in_array( $field->id, $hidden_user_fields, true ) ) {\n\t\t\t\t$field->data->value = __( 'Value suppressed.', 'buddypress' );\n\t\t\t} else {\n\t\t\t\t// Get the raw value for the field.\n\t\t\t\t$field->data->value = BP_XProfile_ProfileData::get_value_byid( $field->id, $request->get_param( 'user_id' ) );\n\t\t\t}\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after XProfile field is fetched via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Field $field    Fetched field object.\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_fields_get_item', $field, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to get information about a specific XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function get_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( bp_current_user_can( 'bp_view', array( 'bp_component' => 'xprofile' ) ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile fields `get_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Whether the user has access to xprofile fields.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_get_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Set additional field properties.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param integer         $field_id The profile field object ID.\n\t * @param WP_REST_Request $request  The request sent to the API.\n\t */\n\tpublic function set_additional_field_properties( $field_id, WP_REST_Request $request ) {\n\t\tif ( ! $field_id ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the edit schema.\n\t\t$schema = $this->get_endpoint_args_for_item_schema( $request->get_method() );\n\n\t\t// Define default visibility property.\n\t\tif ( isset( $schema['default_visibility'] ) ) {\n\t\t\t$default_visibility = $schema['default_visibility']['default'];\n\n\t\t\tif ( $request->get_param( 'default_visibility' ) ) {\n\t\t\t\t$default_visibility = $request->get_param( 'default_visibility' );\n\t\t\t}\n\n\t\t\t// Save the default visibility.\n\t\t\tbp_xprofile_update_field_meta( $field_id, 'default_visibility', $default_visibility );\n\t\t}\n\n\t\t// Define allow custom visibility property.\n\t\tif ( isset( $schema['allow_custom_visibility'] ) ) {\n\t\t\t$allow_custom_visibility = $schema['allow_custom_visibility']['default'];\n\n\t\t\tif ( $request->get_param( 'allow_custom_visibility' ) ) {\n\t\t\t\t$allow_custom_visibility = $request->get_param( 'allow_custom_visibility' );\n\t\t\t}\n\n\t\t\t// Save the default visibility.\n\t\t\tbp_xprofile_update_field_meta( $field_id, 'allow_custom_visibility', $allow_custom_visibility );\n\t\t}\n\n\t\t// Define autolink property.\n\t\tif ( isset( $schema['do_autolink'] ) ) {\n\t\t\t$do_autolink = $schema['do_autolink']['default'];\n\n\t\t\tif ( $request->get_param( 'do_autolink' ) ) {\n\t\t\t\t$do_autolink = $request->get_param( 'do_autolink' );\n\t\t\t}\n\n\t\t\t// Save the default visibility.\n\t\t\tbp_xprofile_update_field_meta( $field_id, 'do_autolink', $do_autolink );\n\t\t}\n\t}\n\n\t/**\n\t * Create a XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function create_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$args = array(\n\t\t\t'field_group_id'    => $request->get_param( 'group_id' ),\n\t\t\t'parent_id'         => $request->get_param( 'parent_id' ),\n\t\t\t'type'              => $request->get_param( 'type' ),\n\t\t\t'name'              => $request->get_param( 'name' ),\n\t\t\t'description'       => $request->get_param( 'description' ),\n\t\t\t'is_required'       => $request->get_param( 'required' ),\n\t\t\t'can_delete'        => $request->get_param( 'can_delete' ),\n\t\t\t'order_by'          => $request->get_param( 'order_by' ),\n\t\t\t'is_default_option' => $request->get_param( 'is_default_option' ),\n\t\t\t'option_order'      => $request->get_param( 'option_order' ),\n\t\t\t'field_order'       => $request->get_param( 'field_order' ),\n\t\t);\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_xprofile_fields_create_item_query_args', $args, $request );\n\n\t\t$field_id = xprofile_insert_field( $args );\n\t\tif ( ! $field_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_create_xprofile_field',\n\t\t\t\t__( 'Cannot create new XProfile field.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Define visibility and autolink field properties.\n\t\t$this->set_additional_field_properties( $field_id, $request );\n\n\t\t$field = $this->get_xprofile_field_object( $field_id );\n\n\t\t// Create Additional fields.\n\t\t$fields_update = $this->update_additional_fields_for_object( $field, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a XProfile field is created via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Field $field     Created field object.\n\t\t * @param WP_REST_Response  $response  The response data.\n\t\t * @param WP_REST_Request   $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_fields_create_item', $field, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to create a XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function create_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to create a XProfile field.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() && bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t$retval = true;\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile fields `create_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_create_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Update a XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function update_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$field = $this->get_xprofile_field_object( $request );\n\n\t\tif ( empty( $field->id ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t__( 'Invalid profile field ID.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 404,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$args = array(\n\t\t\t'field_id'          => $field->id,\n\t\t\t'field_group_id'    => empty( $request->get_param( 'group_id' ) ) ? $field->group_id : $request->get_param( 'group_id' ),\n\t\t\t'parent_id'         => empty( $request->get_param( 'parent_id' ) ) ? $field->parent_id : $request->get_param( 'parent_id' ),\n\t\t\t'type'              => empty( $request->get_param( 'type' ) ) ? $field->type : $request->get_param( 'type' ),\n\t\t\t'name'              => empty( $request->get_param( 'name' ) ) ? $field->name : $request->get_param( 'name' ),\n\t\t\t'description'       => empty( $request->get_param( 'description' ) ) ? $field->description : $request->get_param( 'description' ),\n\t\t\t'is_required'       => empty( $request->get_param( 'required' ) ) ? $field->is_required : $request->get_param( 'required' ),\n\t\t\t'can_delete'        => $request->get_param( 'can_delete' ), // Set to true by default.\n\t\t\t'order_by'          => empty( $request->get_param( 'order_by' ) ) ? $field->order_by : $request->get_param( 'order_by' ),\n\t\t\t'is_default_option' => empty( $request->get_param( 'is_default_option' ) ) ? $field->is_default_option : $request->get_param( 'is_default_option' ),\n\t\t\t'option_order'      => empty( $request->get_param( 'option_order' ) ) ? $field->option_order : $request->get_param( 'option_order' ),\n\t\t\t'field_order'       => empty( $request->get_param( 'field_order' ) ) ? $field->field_order : $request->get_param( 'field_order' ),\n\t\t);\n\n\t\t/**\n\t\t * Filter the query arguments for the request.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array           $args    Key value array of query var to query value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\t$args = apply_filters( 'bp_rest_xprofile_fields_update_item_query_args', $args, $request );\n\n\t\t// Specific check to make sure the Full Name xprofile field will remain undeletable.\n\t\tif ( bp_xprofile_fullname_field_id() === $field->id ) {\n\t\t\t$args['can_delete'] = false;\n\t\t}\n\n\t\t$field_id = xprofile_insert_field( $args );\n\t\tif ( ! $field_id ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_user_cannot_update_xprofile_field',\n\t\t\t\t__( 'Cannot update XProfile field.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Define visibility and autolink field properties.\n\t\t$this->set_additional_field_properties( $field_id, $request );\n\n\t\t$field = $this->get_xprofile_field_object( $field_id );\n\n\t\t// Update Additional fields.\n\t\t$fields_update = $this->update_additional_fields_for_object( $field, $request );\n\n\t\tif ( is_wp_error( $fields_update ) ) {\n\t\t\treturn $fields_update;\n\t\t}\n\n\t\t$retval = array(\n\t\t\t$this->prepare_response_for_collection(\n\t\t\t\t$this->prepare_item_for_response( $field, $request )\n\t\t\t),\n\t\t);\n\n\t\t$response = rest_ensure_response( $retval );\n\n\t\t/**\n\t\t * Fires after a XProfile field is updated via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Field  $field      Updated field object.\n\t\t * @param WP_REST_Response  $response  The response data.\n\t\t * @param WP_REST_Request   $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_fields_update_item', $field, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to update a XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function update_item_permissions_check( $request ) {\n\t\t$retval = $this->delete_item_permissions_check( $request );\n\n\t\t/**\n\t\t * Filter the XProfile fields `update_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_update_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Delete a XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return WP_REST_Response|WP_Error\n\t */\n\tpublic function delete_item( $request ) {\n\t\t// Setting context.\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t// Get the field before it's deleted.\n\t\t$field    = new BP_XProfile_Field( (int) $request->get_param( 'id' ) );\n\t\t$previous = $this->prepare_item_for_response( $field, $request );\n\n\t\tif ( ! $field->delete( $request->get_param( 'delete_data' ) ) ) {\n\t\t\treturn new WP_Error(\n\t\t\t\t'bp_rest_xprofile_field_cannot_delete',\n\t\t\t\t__( 'Could not delete XProfile field.', 'buddypress' ),\n\t\t\t\tarray(\n\t\t\t\t\t'status' => 500,\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Build the response.\n\t\t$response = new WP_REST_Response();\n\t\t$response->set_data(\n\t\t\tarray(\n\t\t\t\t'deleted'  => true,\n\t\t\t\t'previous' => $previous->get_data(),\n\t\t\t)\n\t\t);\n\n\t\t/**\n\t\t * Fires after a XProfile field is deleted via the REST API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param BP_XProfile_Field $field     Deleted field object.\n\t\t * @param WP_REST_Response  $response  The response data.\n\t\t * @param WP_REST_Request   $request   The request sent to the API.\n\t\t */\n\t\tdo_action( 'bp_rest_xprofile_fields_delete_item', $field, $response, $request );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Check if a given request has access to delete a XProfile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param WP_REST_Request $request Full data about the request.\n\t * @return true|WP_Error\n\t */\n\tpublic function delete_item_permissions_check( $request ) {\n\t\t$retval = new WP_Error(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t__( 'Sorry, you are not allowed to delete this field.', 'buddypress' ),\n\t\t\tarray(\n\t\t\t\t'status' => rest_authorization_required_code(),\n\t\t\t)\n\t\t);\n\n\t\tif ( is_user_logged_in() ) {\n\t\t\t$field = $this->get_xprofile_field_object( $request );\n\n\t\t\tif ( empty( $field->id ) ) {\n\t\t\t\t$retval = new WP_Error(\n\t\t\t\t\t'bp_rest_invalid_id',\n\t\t\t\t\t__( 'Invalid field ID.', 'buddypress' ),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'status' => 404,\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} elseif ( bp_current_user_can( 'bp_moderate' ) ) {\n\t\t\t\t$retval = true;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Filter the XProfile fields `delete_item` permissions check.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param true|WP_Error   $retval  Returned value.\n\t\t * @param WP_REST_Request $request The request sent to the API.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_delete_item_permissions_check', $retval, $request );\n\t}\n\n\t/**\n\t * Prepares single XProfile field data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_XProfile_Field $field   XProfile field object.\n\t * @param WP_REST_Request   $request Full data about the request.\n\t * @return WP_REST_Response\n\t */\n\tpublic function prepare_item_for_response( $field, $request ) {\n\t\t$response = rest_ensure_response(\n\t\t\t$this->assemble_response_data( $field, $request )\n\t\t);\n\t\t$response->add_links( $this->prepare_links( $field ) );\n\n\t\t/**\n\t\t * Filter the XProfile field returned from the API.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param WP_REST_Response  $response The response data.\n\t\t * @param WP_REST_Request   $request  Request used to generate the response.\n\t\t * @param BP_XProfile_Field  $field     XProfile field object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_prepare_value', $response, $request, $field );\n\t}\n\n\t/**\n\t * Assembles single XProfile field data to return as an object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_XProfile_Field $field   XProfile field object.\n\t * @param WP_REST_Request   $request Full data about the request.\n\t * @return array\n\t */\n\tpublic function assemble_response_data( $field, $request ) {\n\t\t$data = array(\n\t\t\t'id'                => (int) $field->id,\n\t\t\t'group_id'          => (int) $field->group_id,\n\t\t\t'parent_id'         => (int) $field->parent_id,\n\t\t\t'type'              => $field->type,\n\t\t\t'name'              => $field->name,\n\t\t\t'description'       => array(\n\t\t\t\t'raw'      => $field->description,\n\t\t\t\t'rendered' => apply_filters( 'bp_get_the_profile_field_description', $field->description ),\n\t\t\t),\n\t\t\t'is_required'       => (bool) $field->is_required,\n\t\t\t'can_delete'        => (bool) $field->can_delete,\n\t\t\t'field_order'       => (int) $field->field_order,\n\t\t\t'option_order'      => (int) $field->option_order,\n\t\t\t'order_by'          => strtoupper( $field->order_by ),\n\t\t\t'is_default_option' => (bool) $field->is_default_option,\n\t\t);\n\n\t\tif ( ! empty( $request->get_param( 'fetch_visibility_level' ) && ! empty( $field->visibility_level ) ) ) {\n\t\t\t$data['visibility_level'] = $field->visibility_level;\n\t\t}\n\n\t\tif (\n\t\t\t0 === $data['parent_id']\n\t\t\t&& true === wp_validate_boolean( $request->get_param( 'fetch_field_data' ) )\n\t\t\t&& ! empty( $request->get_param( 'user_id' ) )\n\t\t) {\n\t\t\tif ( isset( $field->data->id ) ) {\n\t\t\t\t$data['data']['id'] = $field->data->id;\n\t\t\t}\n\n\t\t\t$data['data']['value'] = array(\n\t\t\t\t'raw'          => $field->data->value,\n\t\t\t\t'unserialized' => $this->get_profile_field_unserialized_value( $field->data->value ),\n\t\t\t\t'rendered'     => $this->get_profile_field_rendered_value( $field->data->value, $field ),\n\t\t\t);\n\t\t}\n\n\t\t// Adding the options.\n\t\tif ( method_exists( $field, 'get_children' ) ) {\n\t\t\t$data['options'] = array_map(\n\t\t\t\tfunction ( $item ) use ( $request ) {\n\t\t\t\t\treturn $this->assemble_response_data( $item, $request );\n\t\t\t\t},\n\t\t\t\t$field->get_children()\n\t\t\t);\n\t\t}\n\n\t\t$context = ! empty( $request->get_param( 'context' ) ) ? $request->get_param( 'context' ) : 'view';\n\t\t$data    = $this->add_additional_fields_to_object( $data, $request );\n\t\t$data    = $this->filter_response_by_context( $data, $context );\n\n\t\treturn $data;\n\t}\n\n\t/**\n\t * Prepare links for the request.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param BP_XProfile_Field $field XProfile field object.\n\t * @return array\n\t */\n\tprotected function prepare_links( $field ) {\n\t\t$base       = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );\n\t\t$group_base = sprintf( '/%s/%s/', $this->namespace, 'xprofile/groups' );\n\n\t\t// Entity meta.\n\t\t$links = array(\n\t\t\t'self'       => array(\n\t\t\t\t'href' => rest_url( $base . $field->id ),\n\t\t\t),\n\t\t\t'collection' => array(\n\t\t\t\t'href' => rest_url( $base ),\n\t\t\t),\n\t\t\t'group'      => array(\n\t\t\t\t'href'       => rest_url( $group_base . $field->group_id ),\n\t\t\t\t'embeddable' => true,\n\t\t\t),\n\t\t);\n\n\t\t/**\n\t\t * Filter links prepared for the REST response.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array             $links The prepared links of the REST response.\n\t\t * @param BP_XProfile_Field $field XProfile field object.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_prepare_links', $links, $field );\n\t}\n\n\t/**\n\t * Get XProfile field object.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  WP_REST_Request|int $request Request info or integer.\n\t * @return BP_XProfile_Field|string\n\t */\n\tpublic function get_xprofile_field_object( $request ) {\n\t\tif ( is_numeric( $request ) ) {\n\t\t\t$field_id = $request;\n\t\t\t$user_id  = null;\n\t\t} else {\n\t\t\t$field_id = $request->get_param( 'id' );\n\t\t\t$user_id  = $request->get_param( 'user_id' );\n\t\t}\n\n\t\t$field = xprofile_get_field( $field_id, $user_id );\n\n\t\tif ( empty( $field ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn $field;\n\t}\n\n\t/**\n\t * Retrieve the rendered value of a profile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  string                    $value         The raw value of the field.\n\t * @param  integer|BP_XProfile_Field $profile_field The ID or the full object for the field.\n\t * @return string                                   The field value for the display context.\n\t */\n\tpublic function get_profile_field_rendered_value( $value = '', $profile_field = null ) {\n\t\tif ( empty( $value ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\t$profile_field = xprofile_get_field( $profile_field );\n\n\t\tif ( ! isset( $profile_field->id ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\t// Unserialize the BuddyPress way.\n\t\t$value = bp_unserialize_profile_field( $value );\n\n\t\tglobal $field;\n\t\t$reset_global = $field;\n\n\t\t// Set the $field global as the `xprofile_filter_link_profile_data` filter needs it.\n\t\t$field = $profile_field;\n\n\t\t/**\n\t\t * Apply filters to sanitize XProfile field value.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param string $value Value for the profile field.\n\t\t * @param string $type  Type for the profile field.\n\t\t * @param int    $id    ID for the profile field.\n\t\t */\n\t\t$value = apply_filters( 'bp_get_the_profile_field_value', $value, $field->type, $field->id );\n\n\t\t// Reset the global before returning the value.\n\t\t$field = $reset_global;\n\n\t\treturn $value;\n\t}\n\n\t/**\n\t * Retrieve the unserialized value of a profile field.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param  string $value The raw value of the field.\n\t * @return array The unserialized field value.\n\t */\n\tpublic function get_profile_field_unserialized_value( $value = '' ) {\n\t\tif ( empty( $value ) ) {\n\t\t\treturn array();\n\t\t}\n\n\t\t$unserialized_value = maybe_unserialize( $value );\n\t\tif ( ! is_array( $unserialized_value ) ) {\n\t\t\t$unserialized_value = (array) $unserialized_value;\n\t\t}\n\n\t\treturn $unserialized_value;\n\t}\n\n\t/**\n\t * Edit some properties for the CREATABLE & EDITABLE methods.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @param string $method Optional. HTTP method of the request.\n\t * @return array Endpoint arguments.\n\t */\n\tpublic function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {\n\t\t$args = parent::get_endpoint_args_for_item_schema( $method );\n\t\t$key  = 'get_item';\n\n\t\tif ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) {\n\t\t\t$args['description']['type']    = 'string';\n\t\t\t$args['description']['default'] = '';\n\t\t\tunset( $args['description']['properties'] );\n\n\t\t\t// Add specific properties to the edit context.\n\t\t\t$edit_args = array();\n\n\t\t\t// The visibility level chose by the administrator is the default visibility.\n\t\t\t$edit_args['default_visibility']                = $args['visibility_level'];\n\t\t\t$edit_args['default_visibility']['description'] = __( 'Default visibility for the profile field.', 'buddypress' );\n\n\t\t\t// Unset the visibility level which can be the user defined visibility.\n\t\t\tunset( $args['visibility_level'] );\n\n\t\t\t// Add specific properties to the edit context.\n\t\t\t$edit_args['allow_custom_visibility'] = array(\n\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t'description' => __( 'Whether to allow members to set the visibility for the profile field data or not.', 'buddypress' ),\n\t\t\t\t'default'     => 'allowed',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'enum'        => array( 'allowed', 'disabled' ),\n\t\t\t);\n\n\t\t\t$edit_args['do_autolink'] = array(\n\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t'description' => __( 'Autolink status for this profile field', 'buddypress' ),\n\t\t\t\t'default'     => 'off',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'enum'        => array( 'on', 'off' ),\n\t\t\t);\n\n\t\t\t// Set required params for the CREATABLE method.\n\t\t\tif ( WP_REST_Server::CREATABLE === $method ) {\n\t\t\t\t$key                          = 'create_item';\n\t\t\t\t$args['group_id']['required'] = true;\n\t\t\t\t$args['type']['required']     = true;\n\t\t\t\t$args['name']['required']     = true;\n\t\t\t} elseif ( WP_REST_Server::EDITABLE === $method ) {\n\t\t\t\t$key                                        = 'update_item';\n\t\t\t\t$args['can_delete']['default']              = true;\n\t\t\t\t$args['order_by']['default']                = 'asc';\n\t\t\t\t$edit_args['default_visibility']['default'] = 'public';\n\t\t\t}\n\n\t\t\t// Merge arguments.\n\t\t\t$args = array_merge( $args, $edit_args );\n\t\t} elseif ( WP_REST_Server::DELETABLE === $method ) {\n\t\t\t$key = 'delete_item';\n\t\t}\n\n\t\t/**\n\t\t * Filters the method query arguments.\n\t\t *\n\t\t * @since 0.1.0\n\t\t *\n\t\t * @param array  $args   Query arguments.\n\t\t * @param string $method HTTP method of the request.\n\t\t */\n\t\treturn apply_filters( \"bp_rest_xprofile_fields_{$key}_query_arguments\", $args, $method );\n\t}\n\n\t/**\n\t * Get the XProfile field schema, conforming to JSON Schema.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_item_schema() {\n\t\tif ( is_null( $this->schema ) ) {\n\t\t\t$this->schema = array(\n\t\t\t\t'$schema'    => 'http://json-schema.org/draft-04/schema#',\n\t\t\t\t'title'      => 'bp_xprofile_field',\n\t\t\t\t'type'       => 'object',\n\t\t\t\t'properties' => array(\n\t\t\t\t\t'id'                => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'A unique numeric ID for the profile field.', 'buddypress' ),\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'group_id'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the group the field is part of.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'parent_id'         => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The ID of the parent field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'type'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The type for the profile field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => buddypress()->profile->field_types,\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_key',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'name'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The name of the profile field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => 'sanitize_text_field',\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'description'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The description of the profile field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'arg_options' => array(\n\t\t\t\t\t\t\t'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t\t'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database().\n\t\t\t\t\t\t),\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'      => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Content for the profile field, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML content for the profile field, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\t'is_required'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the profile field must have a value.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t\t'can_delete'        => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the profile field can be deleted or not.', 'buddypress' ),\n\t\t\t\t\t\t'default'     => true,\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t\t'field_order'       => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The order of the profile field into the group of fields.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'option_order'      => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The order of the option into the profile field list of options', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'integer',\n\t\t\t\t\t),\n\t\t\t\t\t'order_by'          => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The way profile field\\'s options are ordered.', 'buddypress' ),\n\t\t\t\t\t\t'default'     => 'asc',\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => array( 'asc', 'desc' ),\n\t\t\t\t\t),\n\t\t\t\t\t'is_default_option' => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Whether the option is the default one for the profile field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'boolean',\n\t\t\t\t\t),\n\t\t\t\t\t'visibility_level'  => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Who may see the saved value for this profile field.', 'buddypress' ),\n\t\t\t\t\t\t'default'     => 'public',\n\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t'enum'        => array_keys( bp_xprofile_get_visibility_levels() ),\n\t\t\t\t\t),\n\t\t\t\t\t'options'           => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'Options of the profile field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t),\n\t\t\t\t\t'data'              => array(\n\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t'description' => __( 'The saved value for this profile field.', 'buddypress' ),\n\t\t\t\t\t\t'type'        => 'object',\n\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t'properties'  => array(\n\t\t\t\t\t\t\t'raw'          => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Value for the field, as it exists in the database.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'unserialized' => array(\n\t\t\t\t\t\t\t\t'description' => __( 'Unserialized value for the field, regular string will be casted as array.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'array',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t'rendered'     => array(\n\t\t\t\t\t\t\t\t'description' => __( 'HTML value for the field, transformed for display.', 'buddypress' ),\n\t\t\t\t\t\t\t\t'type'        => 'string',\n\t\t\t\t\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t\t\t\t\t\t'readonly'    => true,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Filters the xprofile field schema.\n\t\t *\n\t\t * @param array $schema The endpoint schema.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_field_schema', $this->add_additional_fields_schema( $this->schema ) );\n\t}\n\n\t/**\n\t * Get the query params for the XProfile fields.\n\t *\n\t * @since 0.1.0\n\t *\n\t * @return array\n\t */\n\tpublic function get_collection_params() {\n\t\t$params                       = parent::get_collection_params();\n\t\t$params['context']['default'] = 'view';\n\n\t\t$params['profile_group_id'] = array(\n\t\t\t'description'       => __( 'ID of the profile group of fields that have profile fields', 'buddypress' ),\n\t\t\t'default'           => 0,\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['hide_empty_groups'] = array(\n\t\t\t'description'       => __( 'Whether to hide profile groups of fields that do not have any profile fields or not.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['user_id'] = array(\n\t\t\t'description'       => __( 'Required if you want to load a specific user\\'s data.', 'buddypress' ),\n\t\t\t'default'           => bp_loggedin_user_id(),\n\t\t\t'type'              => 'integer',\n\t\t\t'sanitize_callback' => 'absint',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['member_type'] = array(\n\t\t\t'description'       => __( 'Limit fields by those restricted to a given member type, or array of member types. If `$user_id` is provided, the value of `$member_type` will be overridden by the member types of the provided user. The special value of \\'any\\' will return only those fields that are unrestricted by member type - i.e., those applicable to any type.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'string' ),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_member_types',\n\t\t\t'validate_callback' => 'bp_rest_validate_member_types',\n\t\t);\n\n\t\t$params['hide_empty_fields'] = array(\n\t\t\t'description'       => __( 'Whether to hide profile fields where the user has not provided data or not.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['fetch_field_data'] = array(\n\t\t\t'description'       => __( 'Whether to fetch data for each field. Requires a $user_id.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['signup_fields_only'] = array(\n\t\t\t'description'       => __( 'Whether to only return signup fields.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['fetch_visibility_level'] = array(\n\t\t\t'description'       => __( 'Whether to fetch the visibility level for each field.', 'buddypress' ),\n\t\t\t'default'           => false,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['include_groups'] = array(\n\t\t\t'description'       => __( 'Ensure result set inludes specific profile field groups.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude_groups'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes specific profile field groups.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'integer' ),\n\t\t\t'sanitize_callback' => 'wp_parse_id_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['exclude_fields'] = array(\n\t\t\t'description'       => __( 'Ensure result set excludes specific profile fields.', 'buddypress' ),\n\t\t\t'default'           => array(),\n\t\t\t'type'              => 'array',\n\t\t\t'items'             => array( 'type' => 'string' ),\n\t\t\t'sanitize_callback' => 'bp_rest_sanitize_string_list',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t$params['update_meta_cache'] = array(\n\t\t\t'description'       => __( 'Whether to pre-fetch xprofilemeta for all retrieved groups, fields, and data.', 'buddypress' ),\n\t\t\t'default'           => true,\n\t\t\t'type'              => 'boolean',\n\t\t\t'sanitize_callback' => 'rest_sanitize_boolean',\n\t\t\t'validate_callback' => 'rest_validate_request_arg',\n\t\t);\n\n\t\t/**\n\t\t * Filters the collection query params.\n\t\t *\n\t\t * @param array $params Query params.\n\t\t */\n\t\treturn apply_filters( 'bp_rest_xprofile_fields_collection_params', $params );\n\t}\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n\t\"name\": \"buddypress\",\n\t\"description\": \"REST API endpoints for BuddyPress\",\n\t\"homepage\": \"https://buddypress.org\",\n\t\"bugs\": {\n\t\t\"url\": \"https://buddypress.trac.wordpress.org/\"\n\t},\n\t\"license\": \"GPL-2.0-or-later\",\n\t\"author\": \"BuddyPress Community\",\n\t\"keywords\": [\n\t\t\"bp-rest\",\n\t\t\"bp-rest-api\",\n\t\t\"buddypress\",\n\t\t\"plugin\"\n\t],\n\t\"devDependencies\": {\n\t\t\"@wordpress/env\": \"^10.35.0\"\n\t},\n\t\"engines\": {\n\t\t\"node\": \">=20.10.0\",\n\t\t\"npm\": \">=10.2.3\"\n\t},\n\t\"scripts\": {\n\t\t\"preinstall\": \"npx check-node-version --package\",\n\t\t\"prewp-env\": \"npx check-node-version --package\",\n\t\t\"wp-env\": \"wp-env\",\n\t\t\"test-php\": \"npm run wp-env run cli -- --env-cwd=wp-content/plugins/BP-REST/ composer test\",\n\t\t\"test-php-multisite\": \"npm run wp-env run cli -- --env-cwd=wp-content/plugins/BP-REST composer test_multi\"\n\t}\n}\n"
  },
  {
    "path": "phpcs.xml.dist",
    "content": "<?xml version=\"1.0\"?>\n<ruleset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"BP REST API Coding Standards Configuration\" xsi:noNamespaceSchemaLocation=\"https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd\">\n\t<description>BP REST API Coding Standards Configuration.</description>\n\n\t<!-- Load BuddyPress Coding standards -->\n\t<rule ref=\"BuddyPress\" />\n\n\t<!--\n\tPass some flags to PHPCS:\n\tp flag: Show progress of the run.\n\ts flag: Show sniff codes in all reports.\n\tv flag: Print processed files.\n\t-->\n\t<arg value=\"psv\" />\n\n\t<!-- Whenever possible, cache the scan results and re-use those for unchanged files on the next scan. -->\n\t<arg name=\"cache\" value=\".phpcs/cache.json\" />\n\n\t<!-- Check 20 files in parallel. -->\n\t<arg name=\"parallel\" value=\"20\"/>\n\n\t<!-- Set severity to 1 to see everything that isn't effectively turned off. -->\n\t<arg name=\"severity\" value=\"1\"/>\n\n\t<!-- What to exclude -->\n\t<exclude-pattern>*/**/tests/</exclude-pattern>\n</ruleset>\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<phpunit\n\tbootstrap=\"tests/bootstrap.php\"\n\tbackupGlobals=\"false\"\n\tcolors=\"true\"\n\tconvertErrorsToExceptions=\"true\"\n\tconvertNoticesToExceptions=\"true\"\n\tconvertWarningsToExceptions=\"true\"\n>\n\t<testsuites>\n\t\t<testsuite name=\"unit\">\n\t\t\t<directory prefix=\"test-\" suffix=\".php\">./tests/testcases/</directory>\n\t\t\t<exclude>tests/testcases/blogs/test-controller.php</exclude>\n\t\t\t<exclude>tests/testcases/attachments/test-blog-avatar-controller.php</exclude>\n\t\t</testsuite>\n\t</testsuites>\n</phpunit>\n"
  },
  {
    "path": "readme.txt",
    "content": "=== BP-REST ===\nContributors:      The BuddyPress Community\nDonate link:       https://buddypress.org\nRequires at least: 6.1\nTested up to:      6.7\nRequires PHP:      5.6\nStable tag:        0.9.0\nLicense:           GNU General Public License v2 or later\nLicense URI:       https://www.gnu.org/licenses/gpl-2.0.html\n\n== Description ==\n\nAccess your BuddyPress site's data through an easy-to-use HTTP REST API.\n\n== Installation ==\n\n= Manual Installation =\n\n1. Upload the entire `/bp-rest` directory to the `/wp-content/plugins/` directory.\n2. Activate BP-REST through the 'Plugins' menu in WordPress.\n\n== Changelog ==\n\n= 0.8.0 =\n* Inclusion in BuddyPress 12.0.0\n\n= 0.7.0 =\n* Inclusion in BuddyPress 11.0.0\n\n= 0.6.0 =\n* Inclusion in BuddyPress 10.0.0\n\n= 0.5.0 =\n* Inclusion in BuddyPress 9.0.0\n\n= 0.4.0 =\n* Inclusion in BuddyPress 8.0.0\n\n= 0.3.0 =\n* Inclusion in BuddyPress 7.0.0\n\n= 0.2.0 =\n* Inclusion in BuddyPress 6.0.0\n\n= 0.1.0 =\n* Inclusion in BuddyPress 5.0.0\n* First release\n\n== Upgrade Notice ==\n\n= 0.1.0 =\nFirst Release\n"
  },
  {
    "path": "tests/bootstrap.php",
    "content": "<?php\n/**\n * PHPUnit bootstrap file\n *\n * @package BP_REST\n */\n\n// Setting PHPUnit polyfills.\nconst WP_TESTS_PHPUNIT_POLYFILLS_PATH = __DIR__ . '/../vendor/yoast/phpunit-polyfills';\n\n// Define constants.\nrequire __DIR__ . '/define-constants.php';\n\nif ( ! file_exists( WP_TESTS_DIR . '/includes/functions.php' ) ) {\n\tdie( \"The WordPress PHPUnit test suite could not be found.\\n\" );\n}\n\nif ( ! file_exists( BP_TESTS_DIR . '/includes/loader.php' ) ) {\n\tdie( \"The BuddyPress plugin could not be found.\\n\" );\n}\n\n// Give access to tests_add_filter() function.\nrequire_once WP_TESTS_DIR . '/includes/functions.php';\n\n/**\n * Manually load the plugins being tested.\n */\nfunction _manually_load_plugins() {\n\n\t// Make sure BP is installed and loaded first.\n\trequire_once BP_TESTS_DIR . '/includes/loader.php';\n\n\t// Load our plugin.\n\trequire_once __DIR__ . '/../bp-rest.php';\n}\ntests_add_filter( 'muplugins_loaded', '_manually_load_plugins' );\n\necho \"Loading WP Testing environment...\\n\";\nrequire_once WP_TESTS_DIR . '/includes/bootstrap.php';\n\necho \"Loading BuddyPress testcases...\\n\";\nrequire_once BP_TESTS_DIR . '/includes/testcase.php';\nrequire_once BP_TESTS_DIR . '/includes/testcase-emails.php';\n\n/**\n * Set component visibility.\n *\n * @param bool $visibility Visibility.\n */\nfunction toggle_component_visibility( $visibility = true ) {\n\t$visibility = $visibility ? 'members' : 'anyone';\n\n\tupdate_option(\n\t\t'_bp_community_visibility',\n\t\tarray(\n\t\t\t'global'   => $visibility,\n\t\t\t'activity' => $visibility,\n\t\t\t'members'  => $visibility,\n\t\t\t'groups'   => $visibility,\n\t\t\t'blogs'    => $visibility,\n\t\t)\n\t);\n}\n"
  },
  {
    "path": "tests/define-constants.php",
    "content": "<?php\n/**\n * Define constants needed by test suite.\n */\n\nif ( ! defined( 'BP_TESTS_DIR' ) ) {\n\tdefine( 'BP_TESTS_DIR', dirname( dirname( dirname( __FILE__ ) ) ) . '/buddypress/tests/phpunit' );\n}\n\n/**\n * Determine where the WP test suite lives. Three options are supported:\n *\n * - Define a WP_DEVELOP_DIR environment variable, which points to a checkout\n *   of the develop.svn.wordpress.org repository (this is recommended)\n * - Define a WP_TESTS_DIR environment variable, which points to a checkout of\n *   WordPress test suite\n * - Assume that we are inside of a develop.svn.wordpress.org setup, and walk\n *   up the directory tree\n */\nif ( false !== getenv( 'WP_TESTS_DIR' ) ) {\n\tdefine( 'WP_TESTS_DIR', getenv( 'WP_TESTS_DIR' ) );\n\tdefine( 'WP_ROOT_DIR', WP_TESTS_DIR );\n} else {\n\t// Support WP_DEVELOP_DIR, as used by some plugins\n\tif ( false !== getenv( 'WP_DEVELOP_DIR' ) ) {\n\t\tdefine( 'WP_ROOT_DIR', getenv( 'WP_DEVELOP_DIR' ) );\n\t} else {\n\t\tdefine( 'WP_ROOT_DIR', dirname( dirname( dirname( dirname( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) ) ) ) );\n\t}\n\n\tdefine( 'WP_TESTS_DIR', WP_ROOT_DIR . '/tests/phpunit' );\n}\n"
  },
  {
    "path": "tests/multisite.xml",
    "content": "<phpunit\n\tbootstrap=\"bootstrap.php\"\n\tbackupGlobals=\"false\"\n\tcolors=\"true\"\n\tconvertErrorsToExceptions=\"true\"\n\tconvertNoticesToExceptions=\"true\"\n\tconvertWarningsToExceptions=\"true\"\n\t>\n\t<php>\n\t\t<const name=\"WP_TESTS_MULTISITE\" value=\"1\" />\n\t</php>\n\t<testsuites>\n\t\t<testsuite name=\"unit\">\n\t\t\t<directory prefix=\"test-\" suffix=\".php\">./testcases/</directory>\n\t\t</testsuite>\n\t</testsuites>\n</phpunit>\n"
  },
  {
    "path": "tests/testcases/activity/test-controller.php",
    "content": "<?php\n/**\n * Activity Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group activity\n */\nclass BP_Test_REST_Activity_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $activity_id;\n\tprotected $user;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\t\t$this->endpoint     = new BP_REST_Activity_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->activity->id;\n\t\t$this->activity_id  = $this->bp::factory()->activity->create();\n\n\t\t$this->user = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\d]+)', $routes );\n\t\t$this->assertCount( 3, $routes[ $this->endpoint_url . '/(?P<id>[\\d]+)' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$this->bp::factory()->activity->create_many( 3 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertTrue( count( $a_ids ) === 4 );\n\t\t$this->assertContains( $this->activity_id, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$this->bp::factory()->activity->create_many( 3 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_multiple_types() {\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'public',\n\t\t) );\n\n\t\t$this->bp::factory()->activity->create( array(\n\t\t\t'component'     => buddypress()->groups->id,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'type' => array( 'activity_update', 'created_group' )\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_type = wp_list_pluck( $response->get_data(), 'type' );\n\n\t\t$this->assertTrue( count( $all_type ) === 2 );\n\t\t$this->assertContains( 'created_group', $all_type );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_invalid_type() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'type' => array( 'invalid_type' )\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_public_groups_items() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t// Current user is $this->user.\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'private',\n\t\t) );\n\n\t\t$g2 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'public',\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$a2 = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => $component,\n\t\t\t'type'      => 'created_group',\n\t\t\t'user_id'   => $this->user,\n\t\t\t'item_id'   => $g2,\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'component' => $component,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertNotContains( $a1, $a_ids );\n\t\t$this->assertContains( $a2, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_from_a_specific_group() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'status' => 'public' ) );\n\t\t$g2 = $this->bp::factory()->group->create( array( 'status' => 'public' ) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => $component,\n\t\t\t'type'      => 'created_group',\n\t\t\t'user_id'   => $this->user,\n\t\t\t'item_id'   => $g2,\n\t\t) );\n\n\t\t$a2 = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => $component,\n\t\t\t'type'      => 'created_group',\n\t\t\t'user_id'   => $this->user,\n\t\t\t'item_id'   => $g2,\n\t\t) );\n\n\t\t$a3 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g2,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$a4 = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => $component,\n\t\t\t'type'      => 'created_group',\n\t\t\t'user_id'   => $this->user,\n\t\t\t'item_id'   => $g1,\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array( 'group_id' => $g2 ) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertEqualSets( [ $a1, $a2 ], $a_ids );\n\t\t$this->assertNotContains( $a3, $a_ids );\n\t\t$this->assertNotContains( $a4, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_private_group_items() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t// Current user is $u.\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'private',\n\t\t\t'creator_id' => $u,\n\t\t) );\n\n\t\t$g2 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'public',\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $u,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$a2 = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => $component,\n\t\t\t'type'      => 'created_group',\n\t\t\t'user_id'   => $this->user,\n\t\t\t'item_id'   => $g2,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'component'  => $component,\n\t\t\t'primary_id' => $g1,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertNotContains( $a2, $a_ids );\n\t\t$this->assertContains( $a1, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_private_group_items_without_access() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t// Current user is $u.\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'private',\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'component'  => $component,\n\t\t\t'primary_id' => $g1,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertEmpty( $a_ids );\n\t\t$this->assertNotContains( $a1, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_private_group_items_with_the_group_id_param() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t// Current user is $u.\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'private',\n\t\t\t'creator_id' => $u,\n\t\t) );\n\n\t\t$g2 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'public',\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $u,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$a2 = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => $component,\n\t\t\t'type'      => 'created_group',\n\t\t\t'user_id'   => $this->user,\n\t\t\t'item_id'   => $g2,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $g1,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertNotContains( $a2, $a_ids );\n\t\t$this->assertContains( $a1, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_private_group_items_for_mod() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'hidden',\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\tgroups_join_group( $g1, $u );\n\t\tgroups_promote_member( $u, $g1, 'mod' );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'activity_update',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'type'      => 'activity_update',\n\t\t\t'group_id'  => $g1,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertContains( $a1, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_private_group_items_for_admin() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$g2 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'private',\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\tgroups_join_group( $g2, $u );\n\t\tgroups_promote_member( $u, $g2, 'admin' );\n\n\t\t$a2 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          =>'activity_update',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g2,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'type'      => 'activity_update',\n\t\t\t'group_id'  => $g2,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertContains( $a2, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_private_group_items_with_group_id_param_without_access() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t// Current user is $u.\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'private',\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $g1,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertEmpty( $a_ids );\n\t\t$this->assertNotContains( $a1, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_paginated_items() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$a = $this->bp::factory()->activity->create( array( 'user_id' => $u ) );\n\t\t$this->bp::factory()->activity->create_many( 5, array( 'user_id' => $u ) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'  => $u,\n\t\t\t'page'     => 2,\n\t\t\t'per_page' => 5,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 6, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 2, $headers['X-WP-TotalPages'] );\n\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\t\t$this->assertContains( $a, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_the_groups_scope() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$component = buddypress()->groups->id;\n\n\t\t// Current user is $this->user.\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'public',\n\t\t) );\n\n\t\t$a2 = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => $component,\n\t\t\t'type'      => 'created_group',\n\t\t\t'user_id'   => $u,\n\t\t\t'item_id'   => $g1,\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'activity_update',\n\t\t\t'user_id'       => $u,\n\t\t\t'item_id'       => $g1,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u,\n\t\t\t'scope'   => 'groups',\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$a_ids = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertContains( $a1, $a_ids );\n\t\t$this->assertContains( $a2, $a_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_favorite() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$this->bp::factory()->activity->create_many( 2 );\n\t\t$a1 = $this->bp::factory()->activity->create();\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\tbp_activity_add_user_favorite( $a1, $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$f_ids = wp_filter_object_list( $response->get_data(), array( 'favorited' => true ), 'AND', 'id' );\n\t\t$f_id  = reset( $f_ids );\n\t\t$this->assertEquals( $a1, $f_id );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_no_favorite() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$this->bp::factory()->activity->create_many( 3, array( 'user_id' => $u ) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$f_ids = wp_filter_object_list( $response->get_data(), array( 'favorited' => false ), 'AND', 'id' );\n\t\t$this->assertTrue( 3 === count( $f_ids ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$activity = $this->endpoint->get_activity_object( $this->activity_id );\n\t\t$this->assertEquals( $this->activity_id, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_activity_data( $activity, $all_data[0], 'view' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$activity = $this->endpoint->get_activity_object( $this->activity_id );\n\t\t$this->assertEquals( $this->activity_id, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_hidden_group_from_activity() {\n\t\t$component = buddypress()->groups->id;\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'hidden',\n\t\t\t'creator_id' => $u1,\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $u1,\n\t\t\t'item_id'       => $g1,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $a1 ) );\n\t\t$request->set_query_params( array( '_embed' => 'group' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data           = $this->server->response_to_data( $response, true )[0];\n\t\t$embedded_group = current( $data['_embedded']['group'][0] );\n\n\t\t$this->assertSame( $g1, $embedded_group['id'] );\n\t\t$this->assertSame( $u1, $embedded_group['creator_id'] );\n\t\t$this->assertSame( 'hidden', $embedded_group['status'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_hidden_group_from_activity_without_permission() {\n\t\t$component = buddypress()->groups->id;\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'hidden',\n\t\t\t'creator_id' => $u1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $u2,\n\t\t\t'item_id'       => $g1,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $a1 ) );\n\t\t$request->set_query_params( array( '_embed' => 'group' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_private_group_from_activity_without_permission() {\n\t\t$component = buddypress()->groups->id;\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status'     => 'private',\n\t\t\t'creator_id' => $u1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $u2,\n\t\t\t'item_id'       => $g1,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $a1 ) );\n\t\t$request->set_query_params( array( '_embed' => 'group' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_for_item_belonging_to_private_group() {\n\t\t$component = buddypress()->groups->id;\n\n\t\t// Current user is $this->user.\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'private',\n\t\t) );\n\n\t\t$a1 = $this->bp::factory()->activity->create( array(\n\t\t\t'component'     => $component,\n\t\t\t'type'          => 'created_group',\n\t\t\t'user_id'       => $this->user,\n\t\t\t'item_id'       => $g1,\n\t\t\t'hide_sitewide' => true,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $a1 );\n\n\t\t// Non-authenticated.\n\t\t$this->bp::set_current_user( 0 );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertEquals( 401, $response->get_status() );\n\n\t\t// Not a member of the group.\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 403, $response->get_status() );\n\n\t\t// Member of the group.\n\t\t$new_member               = new BP_Groups_Member();\n\t\t$new_member->group_id     = $g1;\n\t\t$new_member->user_id      = $u;\n\t\t$new_member->is_confirmed = true;\n\t\t$new_member->save();\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t}\n\n\t/**\n\t * @group render_item\n\t */\n\tpublic function test_render_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'user_id' => $this->user,\n\t\t\t'content' => 'links should be clickable: https://buddypress.org',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $a ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$a_data = reset( $all_data );\n\n\t\t$this->assertTrue( false !== strpos( $a_data['content']['rendered'], '</a>' ) );\n\t}\n\n\t/**\n\t * @group render_item\n\t */\n\tpublic function test_render_item_with_embed_post() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$p = static::factory()->post->create();\n\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'user_id' => $this->user,\n\t\t\t'content' => get_post_embed_url( $p ),\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $a ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$a_data = reset( $all_data );\n\n\t\t$this->assertTrue( false !== strpos( $a_data['content']['rendered'], 'wp-embedded-content' ) );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_activity_data();\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_activity_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_rest_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_activity_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_no_content() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array( 'content' => '' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_create_activity_empty_content', $response, 400 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_in_a_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'component'       => buddypress()->groups->id,\n\t\t\t'primary_item_id' => $g,\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_activity_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_in_a_private_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $this->user,\n\t\t\t'status'     => 'private',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'component'       => buddypress()->groups->id,\n\t\t\t'primary_item_id' => $g,\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_activity_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_in_an_hidden_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $this->user,\n\t\t\t'status'     => 'hidden',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'component'       => buddypress()->groups->id,\n\t\t\t'primary_item_id' => $g,\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_activity_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_and_get_comment() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => 'activity',\n\t\t\t'type'      => 'activity_update',\n\t\t\t'user_id'   => $this->user,\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'type'            => 'activity_comment',\n\t\t\t'primary_item_id' => $a,\n\t\t\t'content'         => 'Activity comment content',\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertTrue( (int) $u === (int) $data[0]['user_id'], 'The user should be able to comment an activity' );\n\n\t\t// Checks the comment is fetched.\n\t\t$expected = $data[0]['id'];\n\n\t\t$get_request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$get_request->set_param( 'context', 'view' );\n\t\t$get_request->set_query_params( array(\n\t\t\t'include'          => $a,\n\t\t\t'display_comments' => 'threaded',\n\t\t) );\n\n\t\t$get_response = $this->server->dispatch( $get_request );\n\t\t$get_data     = $get_response->get_data();\n\n\t\t$this->assertTrue( (int) $expected === (int) $get_data[0]['comments'][0]['id'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_and_get_reply() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => 'activity',\n\t\t\t'type'      => 'activity_update',\n\t\t\t'user_id'   => $u,\n\t\t) );\n\n\t\t$c = bp_activity_new_comment( array(\n\t\t\t'type'        => 'activity_comment',\n\t\t\t'user_id'     => $this->user,\n\t\t\t'activity_id' => $a, // Root activity\n\t\t\t'content'     => 'Activity comment',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t// Add a reply to c\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'type'              => 'activity_comment',\n\t\t\t'primary_item_id'   => $a, // Root activity\n\t\t\t'secondary_item_id' => $c, // Comment Parent\n\t\t\t'content'           => 'Activity comment reply',\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertTrue( (int) $u === (int) $data[0]['user_id'], 'The user should be able to reply to an activity' );\n\n\t\t// Checks the comment is fetched.\n\t\t$expected = $data[0]['id'];\n\n\t\t$get_request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$get_request->set_param( 'context', 'view' );\n\t\t$get_request->set_query_params( array(\n\t\t\t'include'          => $a,\n\t\t\t'display_comments' => 'threaded',\n\t\t) );\n\n\t\t$get_response = $this->server->dispatch( $get_request );\n\t\t$get_data     = $get_response->get_data();\n\n\t\t$this->assertTrue( (int) $expected === (int) $get_data[0]['comments'][0]['comments'][0]['id'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_and_get_comment_in_a_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'component' => buddypress()->groups->id,\n\t\t\t'type'      => 'activity_update',\n\t\t\t'user_id'   => $this->user,\n\t\t\t'item_id'   => $g,\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::set_current_user( $u );\n\t\tgroups_join_group( $g, $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'type'            => 'activity_comment',\n\t\t\t'primary_item_id' => $a,\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertTrue( (int) $u === (int) $data[0]['user_id'], 'The user should be able to comment a group activity' );\n\n\t\t// Check the comment is fetched in group's activities.\n\t\t$expected = $data[0]['id'];\n\n\t\t$get_request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$get_request->set_param( 'context', 'view' );\n\t\t$get_request->set_query_params( array(\n\t\t\t'group_id'         => $g,\n\t\t\t'type'             => 'activity_update',\n\t\t\t'display_comments' => 'threaded',\n\t\t) );\n\t\t$get_response = $this->server->dispatch( $get_request );\n\n\t\t$get_data = $get_response->get_data();\n\t\t$this->assertTrue( (int) $expected === (int) $get_data[0]['comments'][0]['id'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_no_content_in_a_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $this->user,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'component'       => buddypress()->groups->id,\n\t\t\t'primary_item_id' => $g,\n\t\t\t'content'         => '',\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_create_activity_empty_content', $response, 400 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_blog_post_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$p = static::factory()->post->create();\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array(\n\t\t\t'component'         => buddypress()->blogs->id,\n\t\t\t'primary_item_id'   => get_current_blog_id(),\n\t\t\t'secondary_item_id' => $p,\n\t\t\t'type'              => 'new_blog_post',\n\t\t\t'hidden'            => true,\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_activity_response( $response );\n\n\t\t$activity = bp_activity_get( array(\n\t\t\t'show_hidden'  => true,\n\t\t\t'search_terms' => $params['content'],\n\t\t\t'filter'       => array(\n\t\t\t\t'object'       => buddypress()->blogs->id,\n\t\t\t\t'primary_id'   => get_current_blog_id(),\n\t\t\t\t'secondary_id' => $p,\n\t\t\t),\n\t\t) );\n\n\t\t$activity = reset( $activity['activities'] );\n\t\t$a_ids    = wp_list_pluck( $response->get_data(), 'id' );\n\n\t\t$this->assertContains( $activity->id, $a_ids );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$activity = $this->endpoint->get_activity_object( $this->activity_id );\n\t\t$this->assertEquals( $this->activity_id, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_update_activity_response( $response );\n\n\t\t$new_data = $response->get_data();\n\t\t$this->assertNotEmpty( $new_data );\n\n\t\t$new_data = $new_data[0];\n\n\t\t$this->assertEquals( $this->activity_id, $new_data['id'] );\n\t\t$this->assertEquals( $params['content'], $new_data['content']['raw'] );\n\n\t\t$activity = $this->endpoint->get_activity_object( $this->activity_id );\n\t\t$this->assertEquals( $params['content'], $activity->content );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_but_keep_date_the_same() {\n\t\t$activity_date = '1968-12-25 01:23:45';\n\t\t$activity_id   = $this->bp::factory()->activity->create( [ 'recorded_time' => $activity_date ] );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $activity_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\n\t\t$response         = $this->server->dispatch( $request );\n\t\t$new_data         = $response->get_data()[0];\n\t\t$updated_activity = $this->endpoint->get_activity_object( $new_data['id'] );\n\n\t\t// Dates should match.\n\t\t$this->assertEquals( $activity_date, $updated_activity->date_recorded );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group PR448\n\t */\n\tpublic function test_update_item_posted_in_a_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$g = $this->bp::factory()->group->create(\n\t\t\tarray(\n\t\t\t\t'creator_id' => $this->user,\n\t\t\t\t'status'     => 'hidden',\n\t\t\t)\n\t\t);\n\n\t\t$a = $this->bp::factory()->activity->create_and_get(\n\t\t\tarray(\n\t\t\t\t'user_id'       => $this->user,\n\t\t\t\t'component'     => buddypress()->groups->id,\n\t\t\t\t'type'          => 'activity_update',\n\t\t\t\t'item_id'       => $g,\n\t\t\t\t'content'       => 'Random content',\n\t\t\t\t'hide_sitewide' => true, // Private and hidden Group activities are hidden.\n\t\t\t)\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $a->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data(\n\t\t\tarray(\n\t\t\t\t'content'         => 'Updated random content',\n\t\t\t\t'primary_item_id' => $g,\n\t\t\t)\n\t\t);\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_update_activity_response( $response );\n\n\t\t$new_data = $response->get_data();\n\t\t$this->assertNotEmpty( $new_data );\n\n\t\t$new_data = $new_data[0];\n\t\t$activity = $this->endpoint->get_activity_object( $a->id );\n\n\t\t$this->assertEquals( $g, $activity->item_id );\n\t\t$this->assertEquals( $g, $new_data['primary_item_id'] );\n\t\t$this->assertEquals( $a->id, $new_data['id'] );\n\t\t$this->assertSame( (bool) $a->hide_sitewide, $new_data['hidden'], 'Private and hidden group activities should remain hidden' );\n\t\t$this->assertEquals( $params['content'], $new_data['content']['raw'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$request->set_body( wp_json_encode( array( 'type' => 'activity_update' ) ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$activity = $this->endpoint->get_activity_object( $this->activity_id );\n\n\t\t$this->assertEquals( $this->activity_id, $activity->id );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$request->set_body( wp_json_encode( array( 'type' => $activity->type ) ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 401 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_permission() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$a = $this->bp::factory()->activity->create( array( 'user_id' => $u ) );\n\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$activity = $this->endpoint->get_activity_object( $a );\n\t\t$this->assertEquals( $a, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_content() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$a = $this->bp::factory()->activity->create( array( 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$activity = $this->endpoint->get_activity_object( $a );\n\t\t$this->assertEquals( $a, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( [ 'content' => '' ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_update_activity_empty_content', $response, 400 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_type() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$a = $this->bp::factory()->activity->create( array( 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$activity = $this->endpoint->get_activity_object( $a );\n\t\t$this->assertEquals( $a, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = [\n\t\t\t'content'   => 'Activity content',\n\t\t\t'component' => buddypress()->activity->id,\n\t\t];\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_missing_callback_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$activity_id = $this->bp::factory()->activity->create( array(\n\t\t\t'content' => 'Deleted activity',\n\t\t) );\n\n\t\t$activity = $this->endpoint->get_activity_object( $activity_id );\n\t\t$this->assertEquals( $activity_id, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data['deleted'] );\n\n\t\t$this->assertEquals( 'Deleted activity', $data['previous']['content']['raw'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$activity = $this->endpoint->get_activity_object( $this->activity_id );\n\t\t$this->assertEquals( $this->activity_id, $activity->id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_without_permission() {\n\t\t$u           = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$activity_id = $this->bp::factory()->activity->create( array( 'user_id' => $u ) );\n\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$activity = $this->endpoint->get_activity_object( $activity_id );\n\t\t$this->assertEquals( $activity_id, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_favorite\n\t */\n\tpublic function test_update_favorite() {\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'user_id' => $this->user,\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d/favorite', $a ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$f_ids = wp_filter_object_list( $response->get_data(), array( 'favorited' => true ), 'AND', 'id' );\n\t\t$f_id  = reset( $f_ids );\n\t\t$this->assertEquals( $a, $f_id );\n\t}\n\n\t/**\n\t * @group update_favorite\n\t */\n\tpublic function test_update_favorite_remove() {\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'user_id' => $this->user,\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\tbp_activity_add_user_favorite( $a, $u );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d/favorite', $a ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$f_ids = wp_filter_object_list( $response->get_data(), array( 'favorited' => true ), 'AND', 'id' );\n\t\t$this->assertEmpty( $f_ids );\n\t}\n\n\t/**\n\t * @group update_favorite\n\t */\n\tpublic function test_update_favorite_when_disabled() {\n\t\t$a = $this->bp::factory()->activity->create( array(\n\t\t\t'user_id' => $this->user,\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\tadd_filter( 'bp_activity_can_favorite', '__return_false' );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d/favorite', $a ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tremove_filter( 'bp_activity_can_favorite', '__return_false' );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$activity = $this->endpoint->get_activity_object( $this->activity_id );\n\t\t$this->assertEquals( $this->activity_id, $activity->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $activity->id ) );\n\t\t$request->set_query_params( array( 'context' => 'edit' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_activity_data( $activity, $all_data[0], 'edit' );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'activity', 'foo_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Activity Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'bar_value';\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$params = $this->set_activity_data( array( 'foo_field' => $expected ) );\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $create_data[0]['foo_field'] );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $create_data[0]['id'] ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $get_data[0]['foo_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_update_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'activity', 'bar_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Activity Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'foo_value';\n\t\t$a_id     = $this->bp::factory()->activity->create();\n\n\t\t// PUT\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $a_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_activity_data( array( 'bar_field' => 'foo_value' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$update_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $update_data[0]['bar_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\tprotected function check_activity_data( $activity, $data, $context ) {\n\t\t$this->assertEquals( $activity->user_id, $data['user_id'] );\n\t\t$this->assertEquals( $activity->component, $data['component'] );\n\n\t\tif ( 'view' === $context ) {\n\t\t\t$this->assertEquals( wpautop( $activity->content ), $data['content']['rendered'] );\n\t\t} else {\n\t\t\t$this->assertEquals( $activity->content, $data['content']['raw'] );\n\t\t\t$this->assertEquals( bp_rest_prepare_date_response( $activity->date_recorded ), $data['date_gmt'] );\n\t\t}\n\n\t\t$this->assertEquals( $activity->type, $data['type'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $activity->date_recorded, get_date_from_gmt( $activity->date_recorded ) ),\n\t\t\t$data['date']\n\t\t);\n\t\t$this->assertEquals( $activity->id, $data['id'] );\n\t\t$this->assertEquals( bp_activity_get_permalink( $activity->id ), $data['link'] );\n\t\t$this->assertEquals( $activity->item_id, $data['primary_item_id'] );\n\t\t$this->assertEquals( $activity->secondary_item_id, $data['secondary_item_id'] );\n\t\t$this->assertEquals( $activity->action, $data['title'] );\n\t\t$this->assertEquals( $activity->type, $data['type'] );\n\t\t$this->assertEquals( $activity->is_spam ? 'spam' : 'published', $data['status'] );\n\t}\n\n\tprotected function check_add_edit_activity( $response, $update = false ) {\n\t\tif ( $update ) {\n\t\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t} else {\n\t\t\t$this->assertEquals( 201, $response->get_status() );\n\t\t}\n\n\t\t$data     = $response->get_data();\n\t\t$activity = $this->endpoint->get_activity_object( $data['id'] );\n\t\t$this->check_activity_data( $activity, $data, 'edit' );\n\t}\n\n\tprotected function set_activity_data( $args = array() ) {\n\t\treturn wp_parse_args( $args, array(\n\t\t\t'content'   => 'Activity content',\n\t\t\t'type'      => 'activity_update',\n\t\t\t'component' => buddypress()->activity->id,\n\t\t) );\n\t}\n\n\tprotected function check_update_activity_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$headers = $response->get_headers();\n\t\t$this->assertArrayNotHasKey( 'Location', $headers );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$activity = $this->endpoint->get_activity_object( $data[0]['id'] );\n\t\t$this->check_activity_data( $activity, $data[0], 'edit' );\n\t}\n\n\tprotected function check_create_activity_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\n\t\t$activity = $this->endpoint->get_activity_object( $data[0]['id'] );\n\t\t$this->check_activity_data( $activity, $data[0], 'edit' );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 17, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'primary_item_id', $properties );\n\t\t$this->assertArrayHasKey( 'secondary_item_id', $properties );\n\t\t$this->assertArrayHasKey( 'user_id', $properties );\n\t\t$this->assertArrayHasKey( 'link', $properties );\n\t\t$this->assertArrayHasKey( 'component', $properties );\n\t\t$this->assertArrayHasKey( 'type', $properties );\n\t\t$this->assertArrayHasKey( 'title', $properties );\n\t\t$this->assertArrayHasKey( 'content', $properties );\n\t\t$this->assertArrayHasKey( 'date', $properties );\n\t\t$this->assertArrayHasKey( 'date_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'status', $properties );\n\t\t$this->assertArrayHasKey( 'comments', $properties );\n\t\t$this->assertArrayHasKey( 'comment_count', $properties );\n\t\t$this->assertArrayHasKey( 'user_avatar', $properties );\n\t\t$this->assertArrayHasKey( 'hidden', $properties );\n\t\t$this->assertArrayHasKey( 'favorited', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->activity_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn bp_activity_update_meta( $data->id, '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_activity_get_meta( $data['id'], '_' . $attribute );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/attachments/test-blog-avatar-controller.php",
    "content": "<?php\n/**\n * Blog Avatar Endpoints Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group blog-avatar\n */\nclass BP_Test_REST_Attachments_Blog_Avatar_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\t\t$this->endpoint     = new BP_REST_Attachments_Blog_Avatar_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->blogs->id . '/';\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url . '(?P<id>[\\d]+)/avatar';\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 1, $routes[ $endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$u = $this->bp::factory()->user->create();\n\t\t$expected = array(\n\t\t\t'full'  => get_avatar_url( $u, array( 'size' => 150 ) ),\n\t\t\t'thumb' => get_avatar_url( $u, array( 'size' => 50 ) ),\n\t\t);\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$blog_id = $this->bp::factory()->blog->create();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $blog_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertSame( $all_data[0], $expected );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\t$this->skipWithoutMultisite();\n\n\t\ttoggle_component_visibility();\n\n\t\t$blog_id = $this->bp::factory()->blog->create();\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $blog_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_site_icon() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$expected = array(\n\t\t\t'full'  => bp_blogs_default_avatar( '', array( 'object' => 'blog', 'type' => 'full' ) ),\n\t\t\t'thumb' => bp_blogs_default_avatar( '', array( 'object' => 'blog', 'type' => 'thumb' ) ),\n\t\t);\n\n\t\t$u = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$blog_id = $this->bp::factory()->blog->create();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $blog_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'no_user_gravatar', true );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertSame( $all_data[0], $expected );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_no_grav() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$u = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$blog_id = $this->bp::factory()->blog->create();\n\t\t$expected = array(\n\t\t\t'full'  => bp_get_blog_avatar( array( 'blog_id' => $blog_id, 'html' => false, 'type' => 'full' ) ),\n\t\t\t'thumb' => bp_get_blog_avatar( array( 'blog_id' => $blog_id, 'html' => false, 'type' => 'thumb' ) ),\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $blog_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'no_user_gravatar', true );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertSame( $all_data[0], $expected );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_user_id() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$current_user = get_current_user_id();\n\n\t\t$u = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$blog_id = $this->bp::factory()->blog->create( array( 'meta' => array( 'public' => 1 ) ) );\n\n\t\t$this->bp::set_current_user( $current_user );\n\n\t\t// Remove admins.\n\t\tadd_filter( 'bp_blogs_get_blogs', array( $this, 'filter_admin_user_id' ), 10, 1 );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $blog_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tremove_filter( 'bp_blogs_get_blogs', array( $this, 'filter_admin_user_id' ), 10, 1 );\n\n\t\t$this->assertErrorResponse( 'bp_rest_blog_avatar_get_item_user_failed', $response, 500 );\n\t}\n\n\tpublic function filter_admin_user_id( $blog_results ) {\n\t\tunset( $blog_results['blogs'][0]->admin_user_id );\n\n\t\treturn $blog_results;\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_blog_id() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_blog_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$blog_id = $this->bp::factory()->blog->create();\n\n\t\t// Single.\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/avatar', $blog_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 2, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'full', $properties );\n\t\t$this->assertArrayHasKey( 'thumb', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$blog_id = $this->bp::factory()->blog->create();\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/avatar', $blog_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/attachments/test-group-avatar-controller.php",
    "content": "<?php\n/**\n * Group Avatar Endpoints Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group group-avatar\n */\nclass BP_Test_REST_Attachments_Group_Avatar_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $image_file;\n\tprotected $user_id;\n\tprotected $group_id;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Attachments_Group_Avatar_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->groups->id . '/';\n\t\t$this->image_file    = __DIR__ . '/assets/test-image.jpg';\n\n\t\t$this->user_id = $this->bp::factory()->user->create( array(\n\t\t\t'role' => 'administrator',\n\t\t) );\n\n\t\t$this->group_id = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test',\n\t\t\t'description' => 'Group Description',\n\t\t\t'creator_id'  => $this->user_id,\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url . '(?P<group_id>[\\d]+)/avatar';\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( isset( $all_data[0]['full'] ) && isset( $all_data[0]['thumb'] ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_group_id() {\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_no_image() {\n\n\t\t// Disable default url.\n\t\tadd_filter( 'bp_core_fetch_avatar_url', '__return_false' );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_avatar_no_image', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\tif ( 4.9 > (float) $GLOBALS['wp_version'] ) {\n\t\t\t$this->markTestSkipped();\n\t\t}\n\n\t\t$reset_files = $_FILES;\n\t\t$reset_post = $_POST;\n\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\tadd_filter( 'pre_move_uploaded_file', array( $this, 'copy_file' ), 10, 3 );\n\t\tadd_filter( 'bp_core_avatar_dimension', array( $this, 'return_100' ), 10, 1 );\n\n\t\t$_FILES['file'] = array(\n\t\t\t'tmp_name' => $this->image_file,\n\t\t\t'name'     => 'test-image.jpg',\n\t\t\t'type'     => 'image/jpeg',\n\t\t\t'error'    => 0,\n\t\t\t'size'     => filesize( $this->image_file ),\n\t\t);\n\n\t\t$_POST['action'] = 'bp_avatar_upload';\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$request->set_file_params( $_FILES );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tremove_filter( 'pre_move_uploaded_file', array( $this, 'copy_file' ), 10, 3 );\n\t\tremove_filter( 'bp_core_avatar_dimension', array( $this, 'return_100' ), 10, 1 );\n\n\t\t$all_data = $response->get_data();\n\t\t$avatar   = reset( $all_data );\n\n\t\t$this->assertSame( $avatar, array(\n\t\t\t'full'  => bp_core_fetch_avatar(\n\t\t\t\tarray(\n\t\t\t\t\t'object'  => 'group',\n\t\t\t\t\t'type'    => 'full',\n\t\t\t\t\t'item_id' => $this->group_id,\n\t\t\t\t\t'html'    => false,\n\t\t\t\t)\n\t\t\t),\n\t\t\t'thumb' => bp_core_fetch_avatar(\n\t\t\t\tarray(\n\t\t\t\t\t'object'  => 'group',\n\t\t\t\t\t'type'    => 'thumb',\n\t\t\t\t\t'item_id' => $this->group_id,\n\t\t\t\t\t'html'    => false,\n\t\t\t\t)\n\t\t\t),\n\t\t) );\n\n\t\t$_FILES = $reset_files;\n\t\t$_POST  = $reset_post;\n\t}\n\n\tpublic function copy_file( $return, $file, $new_file ) {\n\t\treturn @copy( $file['tmp_name'], $new_file );\n\t}\n\n\tpublic function return_100() {\n\t\treturn 100;\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_image_upload_disabled() {\n\t\tif ( 4.9 > (float) $GLOBALS['wp_version'] ) {\n\t\t\t$this->markTestSkipped();\n\t\t}\n\n\t\t$reset_files = $_FILES;\n\t\t$reset_post  = $_POST;\n\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t// Disabling group avatar upload.\n\t\tadd_filter( 'bp_disable_group_avatar_uploads', '__return_true' );\n\n\t\t$_FILES['file'] = array(\n\t\t\t'tmp_name' => $this->image_file,\n\t\t\t'name'     => 'test-image.jpg',\n\t\t\t'type'     => 'image/jpeg',\n\t\t\t'error'    => 0,\n\t\t\t'size'     => filesize( $this->image_file ),\n\t\t);\n\n\t\t$_POST['action'] = 'bp_avatar_upload';\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$request->set_file_params( $_FILES );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_avatar_disabled', $response, 500 );\n\n\t\tremove_filter( 'bp_disable_group_avatar_uploads', '__return_true' );\n\t\t$_FILES = $reset_files;\n\t\t$_POST  = $reset_post;\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_empty_image() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_avatar_no_image_file', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_group() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_failed() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_avatar_no_uploaded_avatar', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_group() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/avatar', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 2, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'full', $properties );\n\t\t$this->assertArrayHasKey( 'thumb', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/avatar', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/attachments/test-group-cover-controller.php",
    "content": "<?php\n/**\n * Group Cover Endpoints Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group group-cover\n */\nclass BP_Test_REST_Attachments_Group_Cover_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $image_file;\n\tprotected $user_id;\n\tprotected $group_id;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Attachments_Group_Cover_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->groups->id . '/';\n\t\t$this->image_file    = __DIR__ . '/assets/test-image.jpg';\n\n\t\t$this->user_id = $this->bp::factory()->user->create( array(\n\t\t\t'role' => 'administrator',\n\t\t) );\n\n\t\t$this->group_id = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test',\n\t\t\t'description' => 'Group Description',\n\t\t\t'creator_id'  => $this->user_id,\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url . '(?P<group_id>[\\d]+)/cover';\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_no_image() {\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_cover_no_image', $response, 500 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_group_id() {\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/cover', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_no_valid_image_directory() {\n\t\tif ( 4.9 > (float) $GLOBALS['wp_version'] ) {\n\t\t\t$this->markTestSkipped();\n\t\t}\n\n\t\t$this->bp::set_current_user( $this->user_id );\n\t\t$reset_files = $_FILES;\n\n\t\t$_FILES['file'] = array(\n\t\t\t'tmp_name' => $this->image_file,\n\t\t\t'name'     => 'test-image.jpg',\n\t\t\t'type'     => 'image/jpeg',\n\t\t\t'error'    => 0,\n\t\t\t'size'     => filesize( $this->image_file ),\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$request->set_file_params( $_FILES );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_cover_upload_error', $response, 500 );\n\n\t\t$_FILES = $reset_files;\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_image_upload_disabled() {\n\t\tif ( 4.9 > (float) $GLOBALS['wp_version'] ) {\n\t\t\t$this->markTestSkipped();\n\t\t}\n\n\t\t$this->bp::set_current_user( $this->user_id );\n\t\t$reset_files = $_FILES;\n\n\t\t// Disabling group cover upload.\n\t\tadd_filter( 'bp_disable_group_cover_image_uploads', '__return_true' );\n\n\t\t$_FILES['file'] = array(\n\t\t\t'tmp_name' => $this->image_file,\n\t\t\t'name'     => 'test-image.jpg',\n\t\t\t'type'     => 'image/jpeg',\n\t\t\t'error'    => 0,\n\t\t\t'size'     => filesize( $this->image_file ),\n\t\t);\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$request->set_file_params( $_FILES );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_cover_disabled', $response, 500 );\n\n\t\tremove_filter( 'bp_disable_group_cover_image_uploads', '__return_true' );\n\t\t$_FILES = $reset_files;\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_empty_image() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_cover_no_image_file', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_unauthorized_user() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_group_id() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_unauthorized_user() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_group_id() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_failed() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_group_cover_delete_failed', $response, 500 );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 1, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'image', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/cover', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/attachments/test-member-avatar-controller.php",
    "content": "<?php\n/**\n * Member Avatar Endpoints Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group member-avatar\n */\nclass BP_Test_REST_Attachments_Member_Avatar_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $image_file;\n\tprotected $user_id;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Attachments_Member_Avatar_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/members/';\n\t\t$this->image_file    = __DIR__ . '/assets/test-image.jpg';\n\n\t\t$this->user_id = $this->bp::factory()->user->create( array(\n\t\t\t'role' => 'administrator',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url . '(?P<user_id>[\\d]+)/avatar';\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $u1 ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( isset( $all_data[0]['full'] ) && isset( $all_data[0]['thumb'] ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_publicly() {\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( isset( $all_data[0]['full'] ) && isset( $all_data[0]['thumb'] ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_member_id() {\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/avatar', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\tif ( 4.9 > (float) $GLOBALS['wp_version'] ) {\n\t\t\t$this->markTestSkipped();\n\t\t}\n\n\t\t$reset_files = $_FILES;\n\t\t$reset_post = $_POST;\n\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\tadd_filter( 'pre_move_uploaded_file', array( $this, 'copy_file' ), 10, 3 );\n\t\tadd_filter( 'bp_core_avatar_dimension', array( $this, 'return_100' ), 10, 1 );\n\n\t\t$_FILES['file'] = array(\n\t\t\t'tmp_name' => $this->image_file,\n\t\t\t'name'     => 'test-image.jpg',\n\t\t\t'type'     => 'image/jpg',\n\t\t\t'error'    => 0,\n\t\t\t'size'     => filesize( $this->image_file ),\n\t\t);\n\n\t\t$_POST['action'] = 'bp_avatar_upload';\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$request->set_file_params( $_FILES );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tremove_filter( 'pre_move_uploaded_file', array( $this, 'copy_file' ), 10, 3 );\n\t\tremove_filter( 'bp_core_avatar_dimension', array( $this, 'return_100' ), 10, 1 );\n\n\t\t$all_data = $response->get_data();\n\t\t$avatar   = reset( $all_data );\n\n\t\t$this->assertSame(\n\t\t\t$avatar,\n\t\t\tarray(\n\t\t\t\t'full'  => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'object'  => 'user',\n\t\t\t\t\t\t'type'    => 'full',\n\t\t\t\t\t\t'item_id' => $this->user_id,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t\t'thumb' => bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'object'  => 'user',\n\t\t\t\t\t\t'type'    => 'thumb',\n\t\t\t\t\t\t'item_id' => $this->user_id,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\n\t\t$_FILES = $reset_files;\n\t\t$_POST  = $reset_post;\n\t}\n\n\tpublic function copy_file( $return, $file, $new_file ) {\n\t\treturn @copy( $file['tmp_name'], $new_file );\n\t}\n\n\tpublic function return_100() {\n\t\treturn 100;\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_upload_disabled() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t// Disabling member avatar upload.\n\t\tadd_filter( 'bp_disable_avatar_uploads', '__return_true' );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_member_avatar_disabled', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_empty_image() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_member_avatar_no_image_file', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_member_id() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/avatar', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_failed() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_member_avatar_no_uploaded_avatar', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_member_id() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/avatar', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 2, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'full', $properties );\n\t\t$this->assertArrayHasKey( 'thumb', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/avatar', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/attachments/test-member-cover-controller.php",
    "content": "<?php\n/**\n * Member Cover Endpoints Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group member-cover\n */\nclass BP_Test_REST_Attachments_Member_Cover_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user_id;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Attachments_Member_Cover_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/members/';\n\n\t\t$this->user_id = $this->bp::factory()->user->create( array(\n\t\t\t'role' => 'administrator',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url . '(?P<user_id>[\\d]+)/cover';\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_no_image() {\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_member_cover_no_image', $response, 500 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_member_id() {\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/cover', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_upload_disabled() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t// Disabling cover image upload.\n\t\tadd_filter( 'bp_disable_cover_image_uploads', '__return_true' );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_member_cover_disabled', $response, 500 );\n\n\t\tremove_filter( 'bp_disable_cover_image_uploads', '__return_true' );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_empty_image() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_member_cover_no_image_file', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_unauthorized_user() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_member_id() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/cover', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_unauthorized_user() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_member_id() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_failed() {\n\t\t$this->bp::set_current_user( $this->user_id );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_attachments_member_cover_delete_failed', $response, 500 );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 1, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'image', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/cover', $this->user_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/blogs/test-controller.php",
    "content": "<?php\n/**\n * Blogs Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group blogs\n */\nclass BP_Test_REST_Blogs_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $admin;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Blogs_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->blogs->id;\n\t\t$this->admin        = static::factory()->user->create( array(\n\t\t\t'role' => 'administrator',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\d]+)', $routes );\n\t\t$this->assertCount( 1, $routes[ $this->endpoint_url . '/(?P<id>[\\d]+)' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$this->bp::set_current_user( $this->admin );\n\n\t\t$this->bp::factory()->blog->create_many( 2 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$blogs   = $response->get_data();\n\t\t$headers = $response->get_headers();\n\n\t\t$this->assertEquals( 3, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 1, $headers['X-WP-TotalPages'] );\n\t\t$this->assertTrue( count( $blogs ) === 3 );\n\t\t$this->assertTrue( ! empty( $blogs[0] ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$this->bp::set_current_user( $this->admin );\n\n\t\t$blog_id = $this->bp::factory()->blog->create(\n\t\t\tarray( 'title' => 'The Foo Bar Blog' )\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $blog_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$blogs = $response->get_data();\n\n\t\t$this->assertNotEmpty( $blogs );\n\t\t$this->assertSame( $blogs[0]['id'], $blog_id );\n\t\t$this->assertSame( $blogs[0]['name'], 'The Foo Bar Blog' );\n\t\t$this->assertSame( $blogs[0]['user_id'], $this->admin );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\t$this->skipWithoutMultisite();\n\n\t\ttoggle_component_visibility();\n\n\t\t$blog_id = $this->bp::factory()->blog->create(\n\t\t\tarray( 'title' => 'The Foo Bar Blog' )\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $blog_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_blog_id() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_blog_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_latest_post_from_blog_using_subdirectory() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$this->bp::set_current_user( $this->admin );\n\n\t\t$blog_id = $this->bp::factory()->blog->create(\n\t\t\t[\n\t\t\t\t'title'  => 'The Foo Bar Blog',\n\t\t\t\t'domain' => 'foo-bar',\n\t\t\t\t'path'   => '/',\n\t\t\t]\n\t\t);\n\n\t\tswitch_to_blog( $blog_id );\n\n\t\tstatic::factory()->post->create();\n\t\t$latest_post = static::factory()->post->create();\n\t\t$permalink   = get_permalink( $latest_post );\n\t\t$title       = get_the_title( $latest_post );\n\n\t\trestore_current_blog();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $blog_id ) );\n\t\t$request->set_query_params( array( '_embed' => 'post' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $this->server->response_to_data( $response, true )[0];\n\n\t\t$this->assertNotEmpty( $data['_embedded']['post'] );\n\n\t\t$embedded_post = current( $data['_embedded']['post'] );\n\n\t\t$this->assertNotEmpty( $embedded_post );\n\t\t$this->assertSame( $blog_id, $data['id'] );\n\t\t$this->assertSame( $latest_post, $embedded_post['id'] );\n\t\t$this->assertSame( $permalink, $embedded_post['link'] );\n\t\t$this->assertSame( $title, $embedded_post['title']['rendered'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_latest_post_from_blog_using_subdomain() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$this->bp::set_current_user( $this->admin );\n\n\t\t$subdomain = 'cool-site.foo-bar';\n\t\t$blog_id   = $this->bp::factory()->blog->create(\n\t\t\t[\n\t\t\t\t'title'  => 'The Foo Bar Blog',\n\t\t\t\t'domain' => $subdomain,\n\t\t\t\t'path'   => '/',\n\t\t\t]\n\t\t);\n\n\t\tswitch_to_blog( $blog_id );\n\n\t\tstatic::factory()->post->create();\n\t\t$latest_post = static::factory()->post->create();\n\t\t$permalink   = get_permalink( $latest_post );\n\t\t$title       = get_the_title( $latest_post );\n\n\t\trestore_current_blog();\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $blog_id ) );\n\t\t$request->set_query_params( array( '_embed' => 'post' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $this->server->response_to_data( $response, true )[0];\n\n\t\t$this->assertNotEmpty( $data['_embedded']['post'] );\n\n\t\t$embedded_post = current( $data['_embedded']['post'] );\n\n\t\t$this->assertNotEmpty( $embedded_post );\n\t\t$this->assertSame( $blog_id, $data['id'] );\n\t\t$this->assertSame( $subdomain, $data['domain'] );\n\t\t$this->assertSame( $latest_post, $embedded_post['id'] );\n\t\t$this->assertSame( $permalink, $embedded_post['link'] );\n\t\t$this->assertSame( $title, $embedded_post['title']['rendered'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$old_settings = $settings = buddypress()->site_options;\n\n\t\tif ( ! is_array( $settings ) ) {\n\t\t\t$settings = array();\n\t\t}\n\n\t\t$settings['registration'] = 'blog';\n\t\tbuddypress()->site_options = $settings;\n\n\t\t$this->bp::set_current_user( $this->admin );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$request->set_body( wp_json_encode( $this->set_blog_data() ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$blogs = $response->get_data();\n\n\t\t$this->assertNotEmpty( $blogs );\n\t\t$this->assertSame( $blogs[0]['name'], 'Blog Name' );\n\n\t\tbuddypress()->site_options = $old_settings;\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_blog_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_signup_disabled() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$old_settings = $settings = buddypress()->site_options;\n\n\t\tif ( ! is_array( $settings ) ) {\n\t\t\t$settings = array();\n\t\t}\n\n\t\t$settings['registration'] = 'none';\n\t\tbuddypress()->site_options = $settings;\n\n\t\t$this->bp::set_current_user( $this->admin );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_blog_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_blogs_signup_disabled', $response, 500 );\n\n\t\tbuddypress()->site_options = $old_settings;\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_required_field() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$this->bp::set_current_user( $this->admin );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_blog_data();\n\n\t\t// Remove a required field.\n\t\tunset( $params['name'] );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_missing_callback_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tprotected function set_blog_data( $args = array() ) {\n\t\treturn wp_parse_args( $args, array(\n\t\t\t'name'    => 'Cool Blog',\n\t\t\t'title'   => 'Blog Name',\n\t\t\t'user_id' => $this->admin,\n\t\t\t'data'    => [\n\t\t\t\t'public' => 1,\n\t\t\t],\n\t\t) );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_blogs_get_blogmeta( $data['id'], '_' . $attribute );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_get_additional_fields() {\n\t\t$this->skipWithoutMultisite();\n\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'blogs', 'foo_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Blogs single item Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$u = $this->bp::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$blog_id = $this->bp::factory()->blog->create(\n\t\t\tarray(\n\t\t\t\t'title'   => 'The Foo Bar Blog',\n\t\t\t\t'user_id' => $u,\n\t\t\t)\n\t\t);\n\n\t\tbp_blogs_record_existing_blogs();\n\t\tupdate_blog_option( $blog_id, 'blog_public', '1' );\n\n\t\t$expected = 'bar_value';\n\n\t\tbp_blogs_update_blogmeta( $blog_id, '_foo_field', $expected );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'include', array( $blog_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\n\t\t$this->assertTrue( $expected === $get_data[0]['foo_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 11, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'user_id', $properties );\n\t\t$this->assertArrayHasKey( 'name', $properties );\n\t\t$this->assertArrayHasKey( 'path', $properties );\n\t\t$this->assertArrayHasKey( 'domain', $properties );\n\t\t$this->assertArrayHasKey( 'permalink', $properties );\n\t\t$this->assertArrayHasKey( 'description', $properties );\n\t\t$this->assertArrayHasKey( 'last_activity', $properties );\n\t\t$this->assertArrayHasKey( 'last_activity_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'lastest_post_id', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/components/test-controller.php",
    "content": "<?php\n/**\n * Components Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group components\n */\nclass BP_Test_REST_Components_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Components_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/components';\n\t\t$this->user         = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( 10 === count( $all_data ) );\n\n\t\t$component = $this->endpoint->get_component_info( $all_data[0]['name'] );\n\t\t$this->check_component_data( $component, $all_data[0] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_paginated() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'per_page' => 5,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 10, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 2, $headers['X-WP-TotalPages'] );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( 10 === count( $all_data ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_invalid_status() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'status' => 'another',\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_is_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 401 );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_without_permission() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 403 );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_active_permission() {\n\t\t$u = static::factory()->user->create(\n\t\t\tarray(\n\t\t\t\t'role' => 'author',\n\t\t\t)\n\t\t);\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'status', 'active' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$all_features = wp_list_pluck( $all_data, 'features' );\n\t\t$this->assertNotEmpty( array_filter( $all_features ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_active_component_features() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$members_info = wp_list_filter( $all_data, array( 'name' => 'members' ) );\n\t\t$members_info = reset( $members_info );\n\n\t\t$this->assertTrue( $members_info['features']['avatar'] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_inactive_component_features() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\tadd_filter( 'bp_is_messages_star_active', '__return_false' );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tremove_filter( 'bp_is_messages_star_active', '__return_false' );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$messages_info = wp_list_filter( $all_data, array( 'name' => 'messages' ) );\n\t\t$messages_info = reset( $messages_info );\n\n\t\t$this->assertFalse( $messages_info['features']['star'] );\n\t}\n\n\tpublic function deactivate_activity_component( $retval, $component ) {\n\t\tif ( 'activity' === $component ) {\n\t\t\t$retval = false;\n\t\t}\n\n\t\treturn $retval;\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_inactive_component() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\tadd_filter( 'bp_is_active', array( $this, 'deactivate_activity_component' ), 10, 2 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tremove_filter( 'bp_is_active', array( $this, 'deactivate_activity_component' ), 10, 2 );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$components_info = wp_list_filter( $all_data, array( 'name' => 'messages', 'title' => 'Activity Streams' ), 'or' );\n\t\t$features = wp_list_pluck( $components_info, 'features', 'name' );\n\n\t\t$this->assertTrue( $features['messages']['star'] );\n\t\t$this->assertEmpty( $features['activity'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'name'   => 'blogs',\n\t\t\t'action' => 'deactivate',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( 'inactive' === $all_data[0]['status'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_nonexistent_component() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'name'   => 'blogssss',\n\t\t\t'action' => 'deactivate',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_component_nonexistent', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_empty_action() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'name'   => 'blogs',\n\t\t\t'action' => '',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_action() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'name'   => 'blogs',\n\t\t\t'action' => 'update',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_is_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'name'   => 'core',\n\t\t\t'action' => 'activate',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 401 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_permission() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'name'   => 'core',\n\t\t\t'action' => 'activate',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 403 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tprotected function check_component_data( $component, $data ) {\n\t\t$this->assertEquals( $component['name'], $data['name'] );\n\t\t$this->assertEquals( $component['status'], $data['status'] );\n\t\t$this->assertEquals( $component['title'], $data['title'] );\n\t\t$this->assertEquals( $component['description'], $data['description'] );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 6, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'name', $properties );\n\t\t$this->assertArrayHasKey( 'status', $properties );\n\t\t$this->assertArrayHasKey( 'title', $properties );\n\t\t$this->assertArrayHasKey( 'description', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/friends/test-controller.php",
    "content": "<?php\n/**\n * Friends Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group friends\n */\nclass BP_Test_REST_Friends_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $friend;\n\tprotected $user;\n\tprotected $friendship_id;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Friends_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->friends->id;\n\t\t$this->friend       = static::factory()->user->create();\n\t\t$this->user         = static::factory()->user->create(\n\t\t\tarray(\n\t\t\t\t'role'       => 'administrator',\n\t\t\t\t'user_email' => 'admin@example.com',\n\t\t\t\t'user_login' => 'admin_user',\n\t\t\t)\n\t\t);\n\n\t\t$this->friendship_id = $this->create_friendship();\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\w-]+)', $routes );\n\t\t$this->assertCount( 3, $routes[ $this->endpoint_url . '/(?P<id>[\\w-]+)' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->create_friendship();\n\t\t$this->create_friendship();\n\t\t$this->create_friendship();\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'user_id'      => $this->friend,\n\t\t\t\t'per_page'     => 2,\n\t\t\t\t'is_confirmed' => 0,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertNotEmpty( $headers );\n\n\t\t$this->assertEquals( 2, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 1, $headers['X-WP-TotalPages'] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_friendship_data(\n\t\t\t$this->endpoint->get_friendship_object( $this->friendship_id ),\n\t\t\t$all_data[0]\n\t\t);\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_invalid_friend_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_get_item_failed', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_friendship_data(\n\t\t\t[\n\t\t\t\t'initiator_id' => $this->user,\n\t\t\t]\n\t\t);\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$friendship = $response->get_data();\n\t\t$this->assertNotEmpty( $friendship );\n\n\t\t$this->assertSame( $friendship[0]['initiator_id'], $this->user );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_to_myself_from_someone_else() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$params = $this->set_friendship_data(\n\t\t\t[\n\t\t\t\t'initiator_id' => $u1,\n\t\t\t\t'friend_id'    => $u2,\n\t\t\t]\n\t\t);\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_create_item_failed', $response, 403 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_admins_create_item_to_myself_from_someone_else() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$params = $this->set_friendship_data(\n\t\t\t[\n\t\t\t\t'initiator_id' => $u,\n\t\t\t\t'friend_id'    => $this->user,\n\t\t\t]\n\t\t);\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_create_item_failed', $response, 403 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_already_friends() {\n\t\t$user = static::factory()->user->create();\n\n\t\t$this->create_friendship( $user );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$params = $this->set_friendship_data(\n\t\t\t[\n\t\t\t\t'initiator_id' => $this->user,\n\t\t\t\t'friend_id'    => $user\n\t\t\t]\n\t\t);\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_create_item_failed', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_friendship_data();\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_regular_user_can_not_create_friendship_to_others() {\n\t\t$this->bp::set_current_user( static::factory()->user->create() );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_friendship_data();\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_create_item_failed', $response, 403 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_admins_can_create_friendship_to_others() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_friendship_data();\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$friendship = $response->get_data();\n\t\t$this->assertNotEmpty( $friendship );\n\t\t$this->assertNotEmpty( $friendship[0]['initiator_id'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_admins_can_force_friendship_creation() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_friendship_data();\n\t\t$params = array_merge( $params, [ 'force' => true ] );\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$friendship = $response->get_data();\n\n\t\t$this->assertNotEmpty( $friendship );\n\t\t$this->assertTrue( $friendship[0]['is_confirmed'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_regular_users_can_not_force_friendship_creation() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_friendship_data(\n\t\t\t[\n\t\t\t\t'initiator_id' => $u,\n\t\t\t\t'force'        => true,\n\t\t\t]\n\t\t);\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$friendship = $response->get_data();\n\t\t$this->assertNotEmpty( $friendship );\n\n\t\t$this->assertFalse( $friendship[0]['is_confirmed'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_initiator_id() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_friendship_data();\n\t\tunset( $params['initiator_id'] );\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_missing_callback_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_friend_id() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_missing_callback_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->friend );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $all_data );\n\t\t$this->assertTrue( $all_data[0]['is_confirmed'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_initiator_can_not_accept_its_own_friendship_request() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_cannot_update_item', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_friend_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_update_item_failed', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->friend );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$deleted = $response->get_data();\n\n\t\t$this->assertNotEmpty( $deleted );\n\t\t$this->assertTrue( $deleted['deleted'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_using_the_initiator() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$deleted = $response->get_data();\n\n\t\t$this->assertNotEmpty( $deleted );\n\t\t$this->assertTrue( $deleted['deleted'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_reject_and_remove_item_from_database() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->friend );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->user ) );\n\t\t$request->set_body_params( [ 'force' => true ] );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$deleted = $response->get_data();\n\n\t\t$this->assertNotEmpty( $deleted );\n\t\t$this->assertTrue( $deleted['deleted'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_reject_and_remove_item_from_database_using_initiator() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$request->set_body_params( [ 'force' => true ] );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$deleted = $response->get_data();\n\n\t\t$this->assertNotEmpty( $deleted );\n\t\t$this->assertTrue( $deleted['deleted'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_reject_and_remove_item_from_database_using_initiator_and_testing_force() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$request->set_body_params( [ 'force' => 'true' ] );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$deleted = $response->get_data();\n\n\t\t$this->assertNotEmpty( $deleted );\n\t\t$this->assertTrue( $deleted['deleted'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_reject_friendship_request() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->friend );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$deleted = $response->get_data();\n\n\t\t$this->assertNotEmpty( $deleted );\n\t\t$this->assertTrue( $deleted['deleted'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_reject_friendship_with_invalid_friendship_id() {\n\t\t$this->create_friendship();\n\n\t\t$this->bp::set_current_user( $this->friend );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_friends_delete_item_failed', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_reject_friendship_with_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_friendship_data(\n\t\t\t$this->endpoint->get_friendship_object( $this->friendship_id ),\n\t\t\t$all_data[0]\n\t\t);\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 6, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'initiator_id', $properties );\n\t\t$this->assertArrayHasKey( 'friend_id', $properties );\n\t\t$this->assertArrayHasKey( 'is_confirmed', $properties );\n\t\t$this->assertArrayHasKey( 'date_created', $properties );\n\t\t$this->assertArrayHasKey( 'date_created_gmt', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->friend ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n\n\tprotected function set_friendship_data( $args = array() ) {\n\t\treturn wp_parse_args(\n\t\t\t$args,\n\t\t\tarray(\n\t\t\t\t'initiator_id' => static::factory()->user->create(),\n\t\t\t\t'friend_id'    => static::factory()->user->create(),\n\t\t\t)\n\t\t);\n\t}\n\n\tprotected function create_friendship( $u = 0 ) {\n\t\tif ( empty( $u ) ) {\n\t\t\t$u = $this->friend;\n\t\t}\n\n\t\t$friendship                    = new BP_Friends_Friendship();\n\t\t$friendship->initiator_user_id = $this->user;\n\t\t$friendship->friend_user_id    = $u;\n\t\t$friendship->is_confirmed      = 0;\n\t\t$friendship->is_limited        = 0;\n\t\t$friendship->date_created      = bp_core_current_time();\n\t\t$friendship->save();\n\n\t\treturn $friendship->id;\n\t}\n\n\tprotected function check_friendship_data( $friend, $data ) {\n\t\t$this->assertEquals( $friend->id, $data['id'] );\n\t\t$this->assertEquals( $friend->initiator_user_id, $data['initiator_id'] );\n\t\t$this->assertEquals( $friend->friend_user_id, $data['friend_id'] );\n\t\t$this->assertEquals( $friend->is_confirmed, $data['is_confirmed'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $friend->date_created, get_date_from_gmt( $friend->date_created ) ),\n\t\t\t$data['date_created']\n\t\t);\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $friend->date_created ), $data['date_created_gmt'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/groups/test-controller.php",
    "content": "<?php\n/**\n * Group Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group group\n */\nclass BP_Test_REST_Group_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $group_id;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Groups_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->groups->id;\n\t\t$this->user         = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\t$this->group_id = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test',\n\t\t\t'description' => 'Group Description',\n\t\t\t'creator_id'  => $this->user,\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\d]+)', $routes );\n\t\t$this->assertCount( 3, $routes[ $this->endpoint_url . '/(?P<id>[\\d]+)' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$this->bp::factory()->group->create_many( 3 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$this->assertCount( 4, wp_list_pluck( $response->get_data(), 'id' ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$this->bp::factory()->group->create_many( 3 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_including_hidden_groups() {\n\t\t$u  = static::factory()->user->create();\n\t\t$g1 = $this->bp::factory()->group->create();\n\t\t$g2 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$this->bp::add_user_to_group( $u, $g1 );\n\t\t$this->bp::add_user_to_group( $u, $g2 );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'show_hidden' => true,\n\t\t\t'user_id'     => $u,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = $all_data;\n\t\t$status   = wp_list_pluck( $data, 'status' );\n\n\t\t$this->assertCount( 2, wp_list_pluck( $data, 'id' ) );\n\t\t$this->assertTrue( in_array( 'public', $status, true ) );\n\t\t$this->assertTrue( in_array( 'hidden', $status, true ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_including_private_groups() {\n\t\t$u  = static::factory()->user->create();\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'private',\n\t\t) );\n\t\t$g2 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$this->bp::add_user_to_group( $u, $g1 );\n\t\t$this->bp::add_user_to_group( $u, $g2 );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'show_hidden' => true,\n\t\t\t'user_id'     => $u,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = $all_data;\n\t\t$status   = wp_list_pluck( $data, 'status' );\n\n\t\t$this->assertCount( 2, wp_list_pluck( $data, 'id' ) );\n\t\t$this->assertTrue( in_array( 'hidden', $status, true ) );\n\t\t$this->assertTrue( in_array( 'private', $status, true ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_not_including_hidden_groups_when_not_using_user_id_param() {\n\t\t$u = static::factory()->user->create();\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$this->bp::add_user_to_group( $u, $g );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'show_hidden' => true,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = $all_data;\n\n\t\t$this->assertCount( 1, wp_list_pluck( $data, 'id' ) );\n\t\t$this->assertSame( [ 'public' ], wp_list_pluck( $data, 'status' ) );\n\t\t$this->assertSame( [ $this->group_id ], wp_list_pluck( $data, 'id' ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_paginated_items() {\n\t\t$u  = static::factory()->user->create();\n\t\t$g1 = $this->bp::factory()->group->create();\n\t\t$g2 = $this->bp::factory()->group->create();\n\t\t$g3 = $this->bp::factory()->group->create();\n\t\t$g4 = $this->bp::factory()->group->create();\n\t\t$g5 = $this->bp::factory()->group->create();\n\t\t$g6 = $this->bp::factory()->group->create();\n\n\t\t$this->bp::add_user_to_group( $u, $g1 );\n\t\t$this->bp::add_user_to_group( $u, $g2 );\n\t\t$this->bp::add_user_to_group( $u, $g3 );\n\t\t$this->bp::add_user_to_group( $u, $g4 );\n\t\t$this->bp::add_user_to_group( $u, $g5 );\n\t\t$this->bp::add_user_to_group( $u, $g6 );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'per_page' => 5,\n\t\t\t'user_id'  => $u,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 6, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 2, $headers['X-WP-TotalPages'] );\n\t\t$this->assertCount( 5, $response->get_data() );\n\n\t\t// Get results from page 2.\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'page'     => 2,\n\t\t\t'per_page' => 5,\n\t\t\t'user_id'  => $u,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 6, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 2, $headers['X-WP-TotalPages'] );\n\t\t$this->assertCount( 1, $response->get_data() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_edit_context() {\n\t\t$this->bp::factory()->group->create();\n\t\t$this->bp::factory()->group->create();\n\t\t$this->bp::factory()->group->create();\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$admins = array();\n\t\t$groups = $response->get_data();\n\t\tforeach ( $groups as $group ) {\n\t\t\tif ( isset( $group['admins'] ) ) {\n\t\t\t\t$admins = array_merge( $admins, $group['admins'] );\n\t\t\t}\n\t\t}\n\n\t\t$this->assertEmpty( $admins, 'Listing Admins should not be possible for unauthenticated users' );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_edit_context_users_private_data() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$this->bp::factory()->group->create();\n\t\t$this->bp::factory()->group->create();\n\t\t$this->bp::factory()->group->create();\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$has_private_datas = false;\n\t\t$admins = wp_list_pluck( $response->get_data(), 'admins' );\n\n\t\tforeach ( $admins as $admin ) {\n\t\t\tif ( isset( $admin['user_pass'] ) || isset( $admin['user_email'] ) || isset( $admin['user_activation_key'] ) ) {\n\t\t\t\t$has_private_datas = true;\n\t\t\t}\n\t\t}\n\n\t\t$this->assertFalse( $has_private_datas, 'Listing private data should not be possible for any user' );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_extra() {\n\t\t$u1 = $this->bp::factory()->user->create();\n\t\t$u2 = $this->bp::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$now = time();\n\n\t\t$d1 = gmdate( 'Y-m-d H:i:s', $now - 10000 );\n\t\t$d2 = gmdate( 'Y-m-d H:i:s', $now - 1000 );\n\t\t$d3 = gmdate( 'Y-m-d H:i:s', $now - 100 );\n\t\t$d4 = gmdate( 'Y-m-d H:i:s', $now - 500 );\n\n\t\t$a1 = $this->bp::factory()->group->create( array( 'date_created' => $d1 ) );\n\t\t$a2 = $this->bp::factory()->group->create( array( 'date_created' => $d2 ) );\n\t\t$a3 = $this->bp::factory()->group->create( array( 'date_created' => $d3 ) );\n\n\t\t$this->bp::add_user_to_group( $u2, $a3 );\n\n\t\tgroups_update_groupmeta( $a1, 'last_activity', $d4 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'populate_extras', true );\n\t\t$request->set_param( 'type', 'newest' );\n\t\t$request->set_param( 'exclude', $this->group_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = $all_data;\n\n\t\t// Check order.\n\t\t$this->assertSame( array( $a3, $a2, $a1 ), array_map( 'intval', wp_list_pluck( $data, 'id' ) ) );\n\n\t\t// Check member count.\n\t\t$this->assertEquals( array( $a3 ), array_values( wp_filter_object_list( $all_data, array( 'total_member_count' => 2 ), 'AND', 'id' ) ) );\n\n\t\t// check time diff.\n\t\t$not_right_now = wp_filter_object_list( $all_data, array( 'id' => $a1 ), 'AND', 'last_activity_diff' );\n\t\t$not_right_now = reset( $not_right_now );\n\t\t$this->assertEquals( bp_core_time_since( $d4 ), $not_right_now );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_group_types() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\tbp_groups_register_group_type( 'foo' );\n\t\tbp_groups_register_group_type( 'bar' );\n\n\t\t$a1 = $this->bp::factory()->group->create();\n\t\t$a2 = $this->bp::factory()->group->create();\n\t\t$a3 = $this->bp::factory()->group->create();\n\n\t\t$expected_types = array(\n\t\t\t$a1 => array( 'foo' ),\n\t\t\t$a2 => array( 'bar', 'foo' ),\n\t\t\t$a3 => array( 'bar' ),\n\t\t);\n\n\t\tforeach ( $expected_types as $group => $type ) {\n\t\t\tbp_groups_set_group_type( $group, $type );\n\t\t}\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'exclude', $this->group_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertSame( $expected_types, wp_list_pluck( $all_data, 'types', 'id' ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->check_group_data( $group, $all_data[0], 'view' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_unauthenticated_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_unauthenticated() {\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->check_group_data( $group, $all_data[0], 'view' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_group_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_hidden_group() {\n\t\t$u = static::factory()->user->create();\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$group = $this->endpoint->get_group_object( $g );\n\n\t\t$this->bp::add_user_to_group( $u, $group->id );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->check_group_data( $group, $all_data[0], 'view' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_hidden_group_without_being_from_group() {\n\t\t$u = static::factory()->user->create();\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$group = $this->endpoint->get_group_object( $g );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t * @group avatar\n\t */\n\tpublic function test_get_item_with_avatar() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertArrayHasKey( 'thumb', $all_data[0]['avatar_urls'] );\n\t\t$this->assertArrayHasKey( 'full', $all_data[0]['avatar_urls'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t * @group avatar\n\t */\n\tpublic function test_get_item_without_avatar() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\n\t\tadd_filter( 'bp_disable_group_avatar_uploads', '__return_true' );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$all_data = $response->get_data();\n\n\t\tremove_filter( 'bp_disable_group_avatar_uploads', '__return_true' );\n\n\t\t$this->assertArrayNotHasKey( 'avatar_urls', $all_data[0] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_extra() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'populate_extras', true );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$group = reset( $all_data );\n\n\t\t$this->assertTrue( ! is_null( $group['total_member_count'] ) );\n\t\t$this->assertTrue( ! is_null( $group['last_activity'] ) );\n\t\t$this->assertTrue( ! is_null( $group['last_activity_diff'] ) );\n\t}\n\n\t/**\n\t * @group render_item\n\t */\n\tpublic function test_render_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$g = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test',\n\t\t\t'description' => 'links should be clickable: https://buddypress.org',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $g ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$all_data = $response->get_data();\n\t\t$a_data   = reset( $all_data );\n\n\t\t$this->assertTrue( false !== strpos( $a_data['description']['rendered'], '</a>' ) );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_group_data();\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_group_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_rest_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_group_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_group_type() {\n\t\tbp_groups_register_group_type( 'foo' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'types' => 'foo' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( $response->get_data()[0]['types'], array( 'foo' ) );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_no_name() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'name' => '' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_create_group_empty_name', $response, 400 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 401 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_status() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'status' => 'foo' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\t\t$this->assertEquals( $this->group_id, $group->id );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'description' => 'Updated Description' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_update_group_response( $response );\n\n\t\t$new_data = $response->get_data();\n\t\t$new_data = $new_data[0];\n\n\t\t$this->assertEquals( $this->group_id, $new_data['id'] );\n\t\t$this->assertEquals( $params['description'], $new_data['description']['raw'] );\n\n\t\t$group = $this->endpoint->get_group_object( $new_data['id'] );\n\t\t$this->assertEquals( $params['description'], $group->description );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_group_type() {\n\t\tbp_groups_register_group_type( 'foo' );\n\t\tbp_groups_register_group_type( 'bar' );\n\n\t\tbp_groups_set_group_type( $this->group_id, 'bar' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'types' => 'foo' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( $response->get_data()[0]['types'], array( 'foo' ) );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_remove_group_type() {\n\t\tbp_groups_register_group_type( 'bar' );\n\n\t\tbp_groups_set_group_type( $this->group_id, 'bar' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'remove_types' => 'bar' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( $response->get_data()[0]['types'], array() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_append_group_type() {\n\t\tbp_groups_register_group_type( 'foo' );\n\t\tbp_groups_register_group_type( 'bar' );\n\n\t\tbp_groups_set_group_type( $this->group_id, 'bar' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'append_types' => 'foo' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( $response->get_data()[0]['types'], array( 'bar', 'foo' ) );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\n\t\t$this->assertEquals( $this->group_id, $group->id );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 401 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_permission() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$a = $this->bp::factory()->group->create( array( 'creator_id' => $u ) );\n\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$group = $this->endpoint->get_group_object( $a );\n\t\t$this->assertEquals( $a, $group->id );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_site_admins_can_update_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'description' => 'Updated Description' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_update_group_response( $response );\n\n\t\t$new_data = $response->get_data();\n\t\t$new_data = $new_data[0];\n\n\t\t$this->assertEquals( $this->group_id, $new_data['id'] );\n\t\t$this->assertEquals( $params['description'], $new_data['description']['raw'] );\n\n\t\t$group = $this->endpoint->get_group_object( $new_data['id'] );\n\t\t$this->assertEquals( $params['description'], $group->description );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_group_admins_can_update_item() {\n\t\t$u = static::factory()->user->create();\n\n\t\t// Add user to group as an group admin.\n\t\t$this->bp::add_user_to_group( $u, $this->group_id, [ 'is_admin' => true ] );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'description' => 'Group Admin Updated Group' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_update_group_response( $response );\n\n\t\t$new_data = $response->get_data();\n\t\t$new_data = $new_data[0];\n\n\t\t$this->assertEquals( $this->group_id, $new_data['id'] );\n\t\t$this->assertEquals( $params['description'], $new_data['description']['raw'] );\n\n\t\t$group = $this->endpoint->get_group_object( $new_data['id'] );\n\t\t$this->assertEquals( $params['description'], $group->description );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_group_moderators_can_not_update_item() {\n\t\t$u = static::factory()->user->create();\n\n\t\t// Add user to group as a moderator.\n\t\t$this->bp::add_user_to_group( $u, $this->group_id, [ 'is_mod' => true ] );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'description' => 'Moderator Updated' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_status() {\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'status' => 'bar' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertEquals( 'Group Description', $data['previous']['description']['raw'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_without_permission() {\n\t\t$this->bp::set_current_user( static::factory()->user->create() );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_group_moderators_can_not_delete_group() {\n\t\t$u = static::factory()->user->create();\n\n\t\t// Add user to group as a moderator.\n\t\t$this->bp::add_user_to_group( $u, $this->group_id, [ 'is_mod' => true ] );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_site_admins_can_delete_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertEquals( 'Group Description', $data['previous']['description']['raw'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_group_admins_can_delete_group() {\n\t\t$u = static::factory()->user->create();\n\n\t\t// Add user to group as a group admin.\n\t\t$this->bp::add_user_to_group( $u, $this->group_id, [ 'is_admin' => true ] );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertEquals( 'Group Description', $data['previous']['description']['raw'] );\n\t}\n\n\t/**\n\t * @group get_current_user_groups\n\t */\n\tpublic function test_get_current_user_groups() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$groups = array();\n\t\tforeach ( array( 'public', 'private', 'hidden' ) as $status ) {\n\t\t\t$groups[ $status ] = $this->bp::factory()->group->create( array(\n\t\t\t\t'status'      => $status,\n\t\t\t\t'creator_id'  => $u,\n\t\t\t) );\n\t\t}\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/me' );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertEquals( $groups, wp_list_pluck( $all_data, 'id', 'status' ) );\n\t}\n\n\t/**\n\t * @group get_current_user_groups\n\t */\n\tpublic function test_get_current_user_groups_max_one() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$groups = array();\n\t\tforeach ( array( 'public', 'private', 'hidden' ) as $status ) {\n\t\t\t$groups[ $status ] = $this->bp::factory()->group->create( array(\n\t\t\t\t'status'      => $status,\n\t\t\t\t'creator_id'  => $u,\n\t\t\t) );\n\t\t}\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/me' );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'max', 1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$found_groups = wp_list_pluck( $all_data, 'id' );\n\n\t\t$this->assertEquals( 1, count( $found_groups ) );\n\t\t$this->assertTrue( in_array( $found_groups[0], $groups, true ) );\n\t}\n\n\t/**\n\t * @group get_current_user_groups\n\t */\n\tpublic function test_get_current_user_groups_not_loggedin() {\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/me' );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$group = $this->endpoint->get_group_object( $this->group_id );\n\t\t$this->assertEquals( $this->group_id, $group->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_query_params( array( 'context' => 'edit' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->check_group_data( $group, $all_data[0], 'edit' );\n\t}\n\n\tprotected function check_group_data( $group, $data, $context ) {\n\t\t$this->assertEquals( $group->id, $data['id'] );\n\t\t$this->assertEquals( $group->creator_id, $data['creator_id'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $group->date_created, get_date_from_gmt( $group->date_created ) ),\n\t\t\t$data['date_created']\n\t\t);\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $group->date_created ), $data['date_created_gmt'] );\n\t\t$this->assertEquals( $group->enable_forum, $data['enable_forum'] );\n\t\t$this->assertEquals( bp_get_group_url( $group ), $data['link'] );\n\t\t$this->assertEquals( $group->name, $data['name'] );\n\t\t$this->assertEquals( $group->slug, $data['slug'] );\n\t\t$this->assertEquals( $group->status, $data['status'] );\n\t\t$this->assertEquals( $group->parent_id, $data['parent_id'] );\n\t\t$this->assertEquals( [], $data['types'] );\n\n\t\tif ( 'view' === $context ) {\n\t\t\t$this->assertEquals( wpautop( $group->description ), $data['description']['rendered'] );\n\t\t} else {\n\t\t\t$this->assertEquals( $group->description, $data['description']['raw'] );\n\t\t\t$this->assertEquals( $group->total_member_count, $data['total_member_count'] );\n\t\t\t$this->assertEquals(\n\t\t\t\tbp_rest_prepare_date_response( $group->last_activity, get_date_from_gmt( $group->last_activity ) ),\n\t\t\t\t$data['last_activity']\n\t\t\t);\n\t\t\t$this->assertEquals( bp_rest_prepare_date_response( $group->last_activity ), $data['last_activity_gmt'] );\n\t\t}\n\t}\n\n\tprotected function check_add_edit_group( $response, $update = false ) {\n\t\tif ( $update ) {\n\t\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t} else {\n\t\t\t$this->assertEquals( 201, $response->get_status() );\n\t\t}\n\n\t\t$data  = $response->get_data();\n\t\t$group = $this->endpoint->get_group_object( $data['id'] );\n\n\t\t$this->check_group_data( $group, $data, 'edit' );\n\t}\n\n\tprotected function set_group_data( $args = array() ) {\n\t\treturn wp_parse_args( $args, array(\n\t\t\t'name'        => 'Group Name',\n\t\t\t'slug'        => 'group-name',\n\t\t\t'description' => 'Group Description',\n\t\t\t'creator_id'  => $this->user,\n\t\t) );\n\t}\n\n\tprotected function check_update_group_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$headers = $response->get_headers();\n\t\t$this->assertArrayNotHasKey( 'Location', $headers );\n\n\t\t$data = $response->get_data();\n\n\t\t$group = $this->endpoint->get_group_object( $data[0]['id'] );\n\t\t$this->check_group_data( $group, $data[0], 'edit' );\n\t}\n\n\tprotected function check_create_group_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\n\t\t$group = $this->endpoint->get_group_object( $data[0]['id'] );\n\t\t$this->check_group_data( $group, $data[0], 'edit' );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 20, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'creator_id', $properties );\n\t\t$this->assertArrayHasKey( 'name', $properties );\n\t\t$this->assertArrayHasKey( 'slug', $properties );\n\t\t$this->assertArrayHasKey( 'link', $properties );\n\t\t$this->assertArrayHasKey( 'description', $properties );\n\t\t$this->assertArrayHasKey( 'status', $properties );\n\t\t$this->assertArrayHasKey( 'enable_forum', $properties );\n\t\t$this->assertArrayHasKey( 'date_created', $properties );\n\t\t$this->assertArrayHasKey( 'date_created_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'created_since', $properties );\n\t\t$this->assertArrayHasKey( 'admins', $properties );\n\t\t$this->assertArrayHasKey( 'mods', $properties );\n\t\t$this->assertArrayHasKey( 'types', $properties );\n\t\t$this->assertArrayHasKey( 'parent_id', $properties );\n\t\t$this->assertArrayHasKey( 'total_member_count', $properties );\n\t\t$this->assertArrayHasKey( 'last_activity', $properties );\n\t\t$this->assertArrayHasKey( 'last_activity_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'last_activity_diff', $properties );\n\t}\n\n\t/**\n\t * @group item_schema\n\t */\n\tpublic function test_get_item_schema_group_types_enum() {\n\t\t$expected = array( 'foo', 'bar' );\n\n\t\tforeach ( $expected as $type ) {\n\t\t\tbp_groups_register_group_type( $type );\n\t\t}\n\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertArrayHasKey( 'types', $properties );\n\t\t$this->assertEquals( array_values( $properties['types']['enum'] ), $expected );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn groups_update_groupmeta( $data->id, '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn groups_get_groupmeta( $data['id'], '_' . $attribute );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'groups', 'foo_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Groups single item Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'bar_value';\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$params = $this->set_group_data( array( 'foo_field' => $expected ) );\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $create_data[0]['foo_field'] );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $create_data[0]['id'] ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $get_data[0]['foo_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_update_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'groups', 'bar_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Groups single item Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'foo_value';\n\t\t$g_id     = $this->bp::factory()->group->create();\n\n\t\t// PUT\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $g_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_group_data( array( 'bar_field' => 'foo_value' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$update_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $update_data[0]['bar_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/groups/test-group-invites-controller.php",
    "content": "<?php\n/**\n * Group Invites Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group group-invites\n */\nclass BP_Test_REST_Group_Invites_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $group_id;\n\tprotected $g1admin;\n\tprotected $g1;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Group_Invites_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->groups->id . '/invites';\n\t\t$this->user         = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\t$this->group_id = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test',\n\t\t\t'description' => 'Group Description',\n\t\t\t'status'      => 'private',\n\t\t\t'creator_id'  => $this->user,\n\t\t) );\n\n\t\t// Create a group with a group admin that is not a site admin.\n\t\t$this->g1admin = static::factory()->user->create( array(\n\t\t\t'role'       => 'subscriber',\n\t\t\t'user_email' => 'sub@example.com',\n\t\t) );\n\t\t$this->g1 = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test 1',\n\t\t\t'description' => 'Group Description 1',\n\t\t\t'status'      => 'private',\n\t\t\t'creator_id'  => $this->g1admin,\n\t\t) );\n\t\tgroups_update_groupmeta( $this->g1, 'invite_status', 'members' );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// GET and CREATE.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// PUT, etc.\n\t\t$put_endpoint = $this->endpoint_url . '/(?P<invite_id>[\\d]+)';\n\n\t\t$this->assertArrayHasKey( $put_endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $put_endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\t\t$u5 = static::factory()->user->create();\n\n\t\t$this->populate_group_with_invites( [ $u1, $u2, $u3, $u4 ], $this->group_id );\n\n\t\t// As site admin\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$u_ids = wp_list_pluck( $all_data, 'user_id' );\n\n\t\t// Check results.\n\t\t$this->assertEqualSets( [ $u1, $u2, $u3, $u4 ], $u_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\n\t\t$this->populate_group_with_invites( [ $u1, $u2, $u3, $u4 ], $this->group_id );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invites_cannot_get_items', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_as_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\t\t$u5 = static::factory()->user->create();\n\n\t\t$this->populate_group_with_invites( [ $u1, $u2, $u3, $u5 ], $this->g1 );\n\t\t// Red herring\n\t\t$this->populate_group_with_invites( [ $u4 ], $this->group_id );\n\n\t\t$this->bp::set_current_user( $this->g1admin );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->g1,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$u_ids = wp_list_pluck( $all_data, 'user_id' );\n\n\t\t// Check results.\n\t\t$this->assertEqualSets( [ $u1, $u2, $u3, $u5 ], $u_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_as_user() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$inv1 = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\t\t// Red herring\n\t\t$inv2 = groups_invite_user( array(\n\t\t\t'user_id'     => $u2,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\t\t$inv3 = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u1 );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u1,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$inv_ids = wp_list_pluck( $all_data, 'id' );\n\n\t\t// Check results.\n\t\t$this->assertEqualSets( [ $inv1, $inv3 ], $inv_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_as_inviter() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\n\t\t$this->bp::add_user_to_group( $u4, $this->g1 );\n\n\t\tgroups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $u4,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\t\t// Red herring\n\t\tgroups_invite_user( array(\n\t\t\t'user_id'     => $u2,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $this->g1admin,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\t\tgroups_invite_user( array(\n\t\t\t'user_id'     => $u3,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $u4,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u4 );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'inviter_id'               => $u4,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$u_ids = wp_list_pluck( $all_data, 'user_id' );\n\n\t\t// Check results.\n\t\t$this->assertEqualSets( [ $u1, $u3 ], $u_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_not_logged_in() {\n\t\t$this->bp::set_current_user( 0 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_without_permission() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invites_cannot_get_items', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $invite_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertEquals( $u1, $all_data['user_id'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $invite_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_as_user() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u1 );\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $invite_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertEquals( $u1, $all_data['user_id'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_as_inviter() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $this->g1admin,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->g1admin );\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $invite_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertEquals( $u1, $all_data['user_id'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u1,\n\t\t\t'inviter_id' => $this->user,\n\t\t\t'group_id'   => $this->group_id,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertEquals( $u1, $all_data[0]['user_id'] );\n\t\t$this->assertEquals( $this->user, $all_data[0]['inviter_id'] );\n\t\t$this->assertTrue( (bool) $all_data[0]['invite_sent'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_as_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $this->g1admin );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u1,\n\t\t\t'inviter_id' => $this->g1admin,\n\t\t\t'group_id'   => $this->g1,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertEquals( $u1, $all_data[0]['user_id'] );\n\t\t$this->assertEquals( $this->g1admin, $all_data[0]['inviter_id'] );\n\t\t$this->assertTrue( (bool) $all_data[0]['invite_sent'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_inviter_cannot_invite_member_to_group_if_already_member() {\n\t\t// $this->user is a creator of the group.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $this->g1admin,\n\t\t\t'inviter_id' => $this->user,\n\t\t\t'group_id'   => $this->g1,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invite_cannot_create_item', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( 0 );\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u,\n\t\t\t'inviter_id' => $this->user,\n\t\t\t'group_id'   => $this->group_id,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_member_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => REST_TESTS_IMPOSSIBLY_HIGH_NUMBER,\n\t\t\t'inviter_id' => $this->user,\n\t\t\t'group_id'   => $this->group_id,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_inviter_id() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u,\n\t\t\t'inviter_id' => REST_TESTS_IMPOSSIBLY_HIGH_NUMBER,\n\t\t\t'group_id'   => $this->group_id,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_group_id() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u,\n\t\t\t'inviter_id' => $this->user,\n\t\t\t'group_id'   => REST_TESTS_IMPOSSIBLY_HIGH_NUMBER,\n\t\t) );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_permission() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u1,\n\t\t\t'inviter_id' => $this->user,\n\t\t\t'group_id'   => $this->group_id,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invite_cannot_create_item', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertEquals( $u1, $all_data[0]['id'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_as_invitee() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertEquals( $u1, $all_data[0]['id'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invite_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\t\t$this->bp::set_current_user( 0 );\n\t\t$request  = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_permission() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request  = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invite_cannot_update_item', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t// Delete as site admin.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $all_data['deleted'] );\n\t\t$this->assertEquals( $invite_id, $all_data['previous']['id']);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_as_user() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $this->g1admin,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $all_data['deleted'] );\n\t\t$this->assertEquals( $invite_id, $all_data['previous']['id']);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_as_inviter() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::add_user_to_group( $u2, $this->g1 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $u2,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $all_data['deleted'] );\n\t\t$this->assertEquals( $invite_id, $all_data['previous']['id']);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_as_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::add_user_to_group( $u2, $this->g1 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->g1,\n\t\t\t'inviter_id'  => $u2,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->g1admin );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $invite_id );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $all_data['deleted'] );\n\t\t$this->assertEquals( $invite_id, $all_data['previous']['id']);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$u1 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\t\t$this->bp::set_current_user( 0 );\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $invite_id );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u1,\n\t\t\t'group_id'   => $this->group_id,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_without_permission() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$invite_id = groups_invite_user( array(\n\t\t\t'user_id'     => $u1,\n\t\t\t'group_id'    => $this->group_id,\n\t\t\t'inviter_id'  => $this->user,\n\t\t\t'send_invite' => 1,\n\t\t) );\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $invite_id );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'    => $u1,\n\t\t\t'group_id'   => $this->group_id,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invite_cannot_delete_item', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_delete_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invite_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tprotected function check_invited_user_data( $user, $data ) {\n\t\t$this->assertEquals( $user->ID, $data['user_id'] );\n\t\t$this->assertEquals( $user->invite_sent, $data['invite_sent'] );\n\t\t$this->assertEquals( $user->inviter_id, $data['inviter_id'] );\n\t}\n\n\tprotected function populate_group_with_invites( $users, $group_id ) {\n\t\tforeach ( $users as $user_id ) {\n\t\t\tgroups_invite_user( array(\n\t\t\t\t'user_id'     => $user_id,\n\t\t\t\t'group_id'    => $group_id,\n\t\t\t\t'inviter_id'  => $this->user,\n\t\t\t\t'send_invite' => 1,\n\t\t\t) );\n\t\t}\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 9, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'user_id', $properties );\n\t\t$this->assertArrayHasKey( 'invite_sent', $properties );\n\t\t$this->assertArrayHasKey( 'inviter_id', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/members/test-controller.php",
    "content": "<?php\n/**\n * BuddyPress Members Endpoints Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group members\n */\nclass BP_Test_REST_Members_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $server;\n\n\tprotected static $user;\n\tprotected static $site;\n\n\tpublic static function wpSetUpBeforeClass( $factory ) {\n\t\tself::$user = $factory->user->create( array(\n\t\t\t'role'          => 'administrator',\n\t\t\t'user_login'    => 'administrator',\n\t\t\t'user_nicename' => 'administrator',\n\t\t\t'user_email'    => 'admin@example.com',\n\t\t) );\n\n\t\tif ( is_multisite() ) {\n\t\t\tself::$site = $factory->blog->create( array(\n\t\t\t\t'domain' => 'rest.wordpress.org',\n\t\t\t\t'path'   => '/',\n\t\t\t) );\n\n\t\t\tupdate_site_option( 'site_admins', array( 'superadmin' ) );\n\t\t}\n\t}\n\n\tpublic static function wpTearDownAfterClass() {\n\t\tself::delete_user( self::$user );\n\n\t\tif ( is_multisite() ) {\n\t\t\twpmu_delete_blog( self::$site, true );\n\t\t}\n\t}\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\tbuddypress()->members->types = array();\n\n\t\t$this->endpoint     = new BP_REST_Members_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/members';\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\d]+)', $routes );\n\t\t$this->assertCount( 3, $routes[ $this->endpoint_url . '/(?P<id>[\\d]+)' ] );\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/me', $routes );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_ids' => [ $u1, $u2, $u3 ],\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( 3 === count( $all_data ) );\n\n\t\tforeach ( $all_data as $data ) {\n\t\t\t$this->check_user_data( get_userdata( $data['id'] ), $data, 'view' );\n\t\t}\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_ids' => [ $u1, $u2, $u3 ],\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_extra() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t// Set current user.\n\t\t$current_user = get_current_user_id();\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t// u2 is the only one to have a latest_update.\n\t\t$a1 = bp_activity_post_update(\n\t\t\tarray(\n\t\t\t\t'type'    => 'activity_update',\n\t\t\t\t'user_id' => $u2,\n\t\t\t\t'content' => 'The Joshua Tree',\n\t\t\t)\n\t\t);\n\n\t\t$date_last_activity = date( 'Y-m-d H:i:s', bp_core_current_time( true, 'timestamp' ) );\n\n\t\t// u1 is the only one to have a last activity\n\t\tbp_update_user_last_activity( $u1, $date_last_activity );\n\n\t\t$this->bp::set_current_user( $current_user );\n\n\t\t// u1 and u3 are friends.\n\t\tfriends_add_friend( $u1, $u3, true );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'populate_extras' => true,\n\t\t\t\t'user_ids'        => [ $u1, $u2, $u3 ],\n\t\t\t)\n\t\t);\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$members = $response->get_data();\n\t\t$this->assertNotEmpty( $members );\n\n\t\t$this->assertTrue( 3 === count( $members ) );\n\n\t\t$latest_activities = wp_list_pluck( $members, 'last_activity', 'id' );\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $date_last_activity ), $latest_activities[ $u1 ]['date'] );\n\n\t\t$this->assertEquals( array( $u1, $u3 ), array_values( wp_filter_object_list( $members, array( 'total_friend_count' => 1 ), 'AND', 'id' ) ) );\n\n\t\t$latest_updates = wp_list_pluck( $members, 'latest_update', 'id' );\n\t\t$this->assertEquals( $a1, $latest_updates[ $u2 ]['id'] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_paginated_items() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_ids' => [ $u1, $u2, $u3, $u4 ],\n\t\t\t'page'     => 2,\n\t\t\t'per_page' => 2,\n\t\t) );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 4, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 2, $headers['X-WP-TotalPages'] );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\tforeach ( $all_data as $data ) {\n\t\t\t$this->check_user_data( get_userdata( $data['id'] ), $data, 'view' );\n\t\t}\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_types() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\tbp_register_member_type( 'foo' );\n\t\tbp_register_member_type( 'bar' );\n\n\t\t$expected_types = array(\n\t\t\t$u1 => array( 'foo' ),\n\t\t\t$u2 => array( 'bar', 'foo' ),\n\t\t\t$u3 => array( 'bar' ),\n\t\t);\n\n\t\tforeach ( $expected_types as $user => $type ) {\n\t\t\tbp_set_member_type( $user, $type );\n\t\t}\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_ids' => [ $u1, $u2, $u3 ],\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertTrue( 3 === count( $all_data ) );\n\t\t$this->assertSame( $expected_types, wp_list_pluck( $all_data, 'member_types', 'id' ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_filtered_by_xprofile() {\n\t\t$u  = $this->bp::factory()->user->create();\n\t\t$u2 = $this->bp::factory()->user->create();\n\t\t$g  = $this->bp::factory()->xprofile_group->create();\n\t\t$f  = $this->bp::factory()->xprofile_field->create( [\n\t\t\t'field_group_id' => $g,\n\t\t\t'type'           => 'textbox',\n\t\t\t'name'           => 'foo',\n\t\t] );\n\n\t\txprofile_set_field_data( $f, $u, 'bar' );\n\t\txprofile_set_field_data( $f, $u2, 'bar2' );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'xprofile' => [\n\t\t\t\t'args' => [\n\t\t\t\t\t[\n\t\t\t\t\t\t'field' => $f,\n\t\t\t\t\t\t'value' => 'bar',\n\t\t\t\t\t]\n\t\t\t\t]\n\t\t\t],\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\t\t$this->assertTrue( 1 === count( $all_data ) );\n\n\t\t$user_ids = wp_list_pluck( $all_data, 'id' );\n\n\t\t$this->assertFalse( in_array( $u2, $user_ids, true ) );\n\t\t$this->assertSame( array( $u ), $user_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_filtered_by_xprofile_with_and_relation() {\n\t\t$u  = $this->bp::factory()->user->create();\n\t\t$u2 = $this->bp::factory()->user->create();\n\n\t\t$g = $this->bp::factory()->xprofile_group->create();\n\n\t\t$f  = $this->bp::factory()->xprofile_field->create( [\n\t\t\t'field_group_id' => $g,\n\t\t\t'type'           => 'textbox',\n\t\t\t'name'           => 'foo',\n\t\t] );\n\t\t$f2 = $this->bp::factory()->xprofile_field->create( [\n\t\t\t'field_group_id' => $g,\n\t\t\t'type'           => 'textbox',\n\t\t\t'name'           => 'bar',\n\t\t] );\n\n\t\txprofile_set_field_data( $f, $u, 'foo1' );\n\t\txprofile_set_field_data( $f2, $u, 'bar1' );\n\n\t\txprofile_set_field_data( $f, $u2, 'foo1' );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'xprofile' => [\n\t\t\t\t'relation' => 'and',\n\t\t\t\t'args' => [\n\t\t\t\t\t[\n\t\t\t\t\t\t'field' => $f,\n\t\t\t\t\t\t'value' => 'foo1',\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t'field' => $f2,\n\t\t\t\t\t\t'value' => 'bar1',\n\t\t\t\t\t]\n\t\t\t\t]\n\t\t\t],\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$user_ids = wp_list_pluck( $all_data, 'id' );\n\n\t\t$this->assertNotEmpty( $all_data );\n\t\t$this->assertTrue( 1 === count( $all_data ) );\n\t\t$this->assertFalse( in_array( $u2, $user_ids, true ) );\n\t\t$this->assertSame( array( $u ), $user_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_filtered_by_xprofile_with_or_relation() {\n\t\t$u  = $this->bp::factory()->user->create();\n\t\t$u2 = $this->bp::factory()->user->create();\n\t\t$u3 = $this->bp::factory()->user->create();\n\n\t\t$g = $this->bp::factory()->xprofile_group->create();\n\n\t\t$f  = $this->bp::factory()->xprofile_field->create( [\n\t\t\t'field_group_id' => $g,\n\t\t\t'type'           => 'textbox',\n\t\t\t'name'           => 'foo',\n\t\t] );\n\t\t$f2 = $this->bp::factory()->xprofile_field->create( [\n\t\t\t'field_group_id' => $g,\n\t\t\t'type'           => 'textbox',\n\t\t\t'name'           => 'bar',\n\t\t] );\n\n\t\txprofile_set_field_data( $f, $u, 'foo1' );\n\t\txprofile_set_field_data( $f2, $u, 'bar1' );\n\n\t\txprofile_set_field_data( $f, $u2, 'foo2' );\n\t\txprofile_set_field_data( $f2, $u2, 'bar2' );\n\n\t\txprofile_set_field_data( $f, $u3, 'foo3' );\n\t\txprofile_set_field_data( $f2, $u3, 'bar3' );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'xprofile' => [\n\t\t\t\t'relation' => 'or',\n\t\t\t\t'args' => [\n\t\t\t\t\t[\n\t\t\t\t\t\t'field' => $f,\n\t\t\t\t\t\t'value' => 'foo1',\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t'field' => $f2,\n\t\t\t\t\t\t'value' => 'bar3',\n\t\t\t\t\t]\n\t\t\t\t]\n\t\t\t],\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$user_ids = wp_list_pluck( $all_data, 'id' );\n\n\t\t$this->assertNotEmpty( $all_data );\n\t\t$this->assertTrue( 2 === count( $all_data ) );\n\t\t$this->assertFalse( in_array( $u2, $user_ids, true ) );\n\t\t$this->assertSame( array( $u3, $u ), $user_ids );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$u = static::factory()->user->create();\n\n\t\t// Register and set member types.\n\t\tbp_register_member_type( 'foo' );\n\t\tbp_register_member_type( 'bar' );\n\t\tbp_set_member_type( $u, 'foo' );\n\t\tbp_set_member_type( $u, 'bar', true );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$this->check_get_user_response( $response );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$u = static::factory()->user->create();\n\n\t\t// Register and set member types.\n\t\tbp_register_member_type( 'foo' );\n\t\tbp_register_member_type( 'bar' );\n\t\tbp_set_member_type( $u, 'foo' );\n\t\tbp_set_member_type( $u, 'bar', true );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_extras() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Set current user.\n\t\t$current_user = get_current_user_id();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$a1 = bp_activity_post_update(\n\t\t\tarray(\n\t\t\t\t'type'    => 'activity_update',\n\t\t\t\t'user_id' => $u1,\n\t\t\t\t'content' => '<a href=\"https://buddypress.org\">BuddyPress</a> is awesome!',\n\t\t\t)\n\t\t);\n\n\t\tfriends_add_friend( $u1, $u2, true );\n\n\t\t$date_last_activity = date( 'Y-m-d H:i:s', bp_core_current_time( true, 'timestamp' ) );\n\t\tbp_update_user_last_activity( $u1, $date_last_activity );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $u1 ) );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'populate_extras' => true,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$member = $response->get_data();\n\t\t$this->assertNotEmpty( $member );\n\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $date_last_activity, get_date_from_gmt( $date_last_activity ) ),\n\t\t\t$member['last_activity']['date']\n\t\t);\n\t\t$this->assertEquals( $member['latest_update']['id'], $a1 );\n\t\t$this->assertEquals( 1, $member['total_friend_count'] );\n\n\t\t$this->bp::set_current_user( $current_user );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_me_extras() {\n\t\t// Set current user.\n\t\t$current_user = get_current_user_id();\n\t\t$this->bp::set_current_user( self::$user );\n\n\t\t$request  = new WP_REST_Request( 'GET', $this->endpoint_url . '/me' );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'populate_extras' => true,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$me = $response->get_data();\n\t\t$this->assertNotEmpty( $me );\n\n\t\t$this->assertEquals( 'right now', $me['last_activity']['timediff'] );\n\n\t\t$this->bp::set_current_user( $current_user );\n\t}\n\n\t/**\n\t * @group get_item\n\t * @group avatar\n\t */\n\tpublic function test_get_item_without_avatar() {\n\t\t$u = static::factory()->user->create();\n\n\t\t// Register and set member types.\n\t\tbp_register_member_type( 'foo' );\n\t\tbp_register_member_type( 'bar' );\n\t\tbp_set_member_type( $u, 'foo' );\n\t\tbp_set_member_type( $u, 'bar', true );\n\n\t\tbuddypress()->avatar->show_avatars = false;\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tbuddypress()->avatar->show_avatars = true;\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$this->assertArrayNotHasKey( 'avatar_urls', $response->get_data() );\n\t}\n\n\t/**\n\t * @group get_item\n\t * @group avatar\n\t */\n\tfunction test_get_item_schema_show_avatar() {\n\t\tbuddypress()->avatar->show_avatars = false;\n\n\t\t// Re-initialize the controller to cache-bust schemas from prior test runs.\n\t\t$GLOBALS['wp_rest_server']->override_by_default = true;\n\t\t$controller                                     = new BP_REST_Members_Endpoint();\n\t\t$controller->register_routes();\n\t\t$GLOBALS['wp_rest_server']->override_by_default = false;\n\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\tbuddypress()->avatar->show_avatars = true;\n\n\t\t$this->assertArrayNotHasKey( 'avatar_urls', $properties );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_id() {\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->skipWithMultisite();\n\n\t\t$this->allow_user_to_manage_multisite();\n\n\t\t$params = array(\n\t\t\t'password'   => 'testpassword',\n\t\t\t'email'      => 'test@example.com',\n\t\t\t'user_login' => 'testuser',\n\t\t\t'name'       => 'Test User',\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( 'Test User', $data['name'] );\n\t\t$this->check_add_edit_user_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_permission() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$params = array(\n\t\t\t'password'   => 'testpassword',\n\t\t\t'email'      => 'test@example.com',\n\t\t\t'user_login' => 'testuser',\n\t\t\t'name'       => 'Test User',\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_cannot_create_user', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$u = static::factory()->user->create( array(\n\t\t\t'email' => 'test@example.com',\n\t\t\t'name'  => 'User Name',\n\t\t) );\n\n\t\t$this->allow_user_to_manage_multisite();\n\n\t\t$userdata      = get_userdata( $u );\n\t\t$pw_before     = $userdata->user_pass;\n\t\t$_POST['name'] = 'New User Name';\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( $_POST );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->check_add_edit_user_response( $response, true );\n\n\t\t$new_data = $response->get_data();\n\t\t$this->assertNotEmpty( $new_data );\n\n\t\t$this->assertEquals( $pw_before, $userdata->user_pass );\n\t\t$this->assertEquals( 'New User Name', $new_data['name'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$request->set_param( 'username', 'test_json_user' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( self::$user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( array(\n\t\t\t'id'       => '156',\n\t\t\t'username' => 'test_user',\n\t\t\t'password' => 'reallysimplepassword',\n\t\t\t'email'    => 'reallydumbguy@example.com',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_permission() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $u2 ) );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( $_POST );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * This test is there to make sure we are handling the `types` parameter\n\t * that was used before BP REST 0.3.0 and BuddyPress 7.0.0.\n\t *\n\t * @group update_item\n\t */\n\tpublic function test_update_item_types() {\n\t\t$this->skipWithMultisite();\n\n\t\t$u = static::factory()->user->create( array(\n\t\t\t'email' => 'member@type.com',\n\t\t\t'name'  => 'User Name',\n\t\t) );\n\n\t\t$this->bp::set_current_user( self::$user );\n\t\tbp_register_member_type( 'membertypeone' );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( array(\n\t\t\t'types' => 'membertypeone',\n\t\t) );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertSame( 'membertypeone', reset( $data['member_types'] ) );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_member_type_as_regular_user() {\n\t\t$u = static::factory()->user->create( array(\n\t\t\t'email' => 'member@type.com',\n\t\t\t'name'  => 'User Name',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u );\n\t\tbp_register_member_type( 'membertypeone' );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( array(\n\t\t\t'member_type' => 'membertypeone',\n\t\t) );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_member_type_as_admin_user() {\n\t\t$this->bp::set_current_user( self::$user );\n\t\tbp_register_member_type( 'membertypeone' );\n\t\tbp_register_member_type( 'membertypetwo' );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', self::$user ) );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( array(\n\t\t\t'member_type' => 'membertypeone,membertypetwo',\n\t\t) );\n\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data = $response->get_data();\n\n\t\t$member_types = array( 'membertypeone' ,'membertypetwo' );\n\n\t\t$this->assertSame( $data['member_types'], $member_types );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->skipWithMultisite();\n\n\t\t$u = static::factory()->user->create( array( 'display_name' => 'Deleted User' ) );\n\n\t\t$this->allow_user_to_manage_multisite();\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$request->set_param( 'force', true );\n\t\t$request->set_param( 'reassign', false );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertTrue( $data['deleted'] );\n\t\t$this->assertEquals( 'Deleted User', $data['previous']['name'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_id() {\n\t\t$this->bp::set_current_user( self::$user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->set_param( 'force', true );\n\t\t$request->set_param( 'reassign', false );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$request->set_param( 'force', true );\n\t\t$request->set_param( 'reassign', false );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_without_permission() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $u2 ) );\n\t\t$request->set_param( 'force', true );\n\t\t$request->set_param( 'reassign', false );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_current_item() {\n\t\t$u = static::factory()->user->create( array( 'display_name' => 'Deleted User' ) );\n\t\t$current_user = get_current_user_id();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/me' );\n\t\t$request->set_param( 'force', true );\n\t\t$request->set_param( 'reassign', false );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertTrue( $data['deleted'] );\n\t\t$this->assertEquals( 'Deleted User', $data['previous']['name'] );\n\n\t\t$this->bp::set_current_user( $u );\n\t}\n\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( self::$user );\n\n\t\t$request = new WP_REST_Request();\n\t\t$request->set_param( 'context', 'view' );\n\t\t$user = get_user_by( 'id', get_current_user_id() );\n\t\t$data = $this->endpoint->prepare_item_for_response( $user, $request );\n\n\t\t$this->check_get_user_response( $data, 'view' );\n\t}\n\n\tprotected function check_get_user_response( $response, $context = 'view' ) {\n\t\t$data = $response->get_data();\n\t\t$user = get_userdata( $data['id'] );\n\n\t\t$this->check_user_data( $user, $data, $context );\n\t}\n\n\tprotected function check_add_edit_user_response( $response, $update = false ) {\n\t\tif ( $update ) {\n\t\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t} else {\n\t\t\t$this->assertEquals( 201, $response->get_status() );\n\t\t}\n\n\t\t$data = $response->get_data();\n\t\t$this->check_user_data( get_userdata( $data['id'] ), $data, 'edit' );\n\t}\n\n\tprotected function check_user_data( $user, $data, $context ) {\n\t\t$this->assertEquals( $user->ID, $data['id'] );\n\t\t$this->assertEquals( $user->display_name, $data['name'] );\n\t\t$this->assertEquals( $user->user_login, $data['user_login'] );\n\t\t$this->assertArrayHasKey( 'avatar_urls', $data );\n\t\t$this->assertArrayHasKey( 'thumb', $data['avatar_urls'] );\n\t\t$this->assertArrayHasKey( 'full', $data['avatar_urls'] );\n\t\t$this->assertArrayHasKey( 'member_types', $data );\n\t\t$this->assertArrayHasKey( 'xprofile', $data );\n\t\t$this->assertArrayHasKey( 'friendship_status', $data );\n\t\t$this->assertArrayHasKey( 'friendship_status_slug', $data );\n\t\t$this->assertEquals(\n\t\t\tbp_members_get_user_url( $data['id'] ),\n\t\t\t$data['link']\n\t\t);\n\n\t\tif ( 'edit' === $context ) {\n\t\t\t$this->assertEquals( (array) array_keys( $user->allcaps ), $data['capabilities'] );\n\t\t\t$this->assertEquals( (array) array_keys( $user->caps ), $data['extra_capabilities'] );\n\t\t\t$this->assertEquals( (array) array_values( $user->roles ), $data['roles'] );\n\t\t\t$this->assertEquals(\n\t\t\t\tbp_rest_prepare_date_response( $user->user_registered, get_date_from_gmt( $user->user_registered ) ),\n\t\t\t\t$data['registered_date']\n\t\t\t);\n\t\t\t$this->assertEquals( bp_rest_prepare_date_response( $user->user_registered ), $data['registered_date_gmt'] );\n\t\t} else {\n\t\t\t$this->assertArrayNotHasKey( 'roles', $data );\n\t\t\t$this->assertArrayNotHasKey( 'capabilities', $data );\n\t\t\t$this->assertArrayNotHasKey( 'extra_capabilities', $data );\n\t\t}\n\t}\n\n\tprotected function allow_user_to_manage_multisite() {\n\t\t$this->bp::set_current_user( self::$user );\n\n\t\tif ( is_multisite() ) {\n\t\t\tupdate_site_option( 'site_admins', array( wp_get_current_user()->user_login ) );\n\t\t}\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 20, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'avatar_urls', $properties );\n\t\t$this->assertArrayHasKey( 'capabilities', $properties );\n\t\t$this->assertArrayHasKey( 'extra_capabilities', $properties );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'link', $properties );\n\t\t$this->assertArrayHasKey( 'name', $properties );\n\t\t$this->assertArrayHasKey( 'mention_name', $properties );\n\t\t$this->assertArrayHasKey( 'registered_date', $properties );\n\t\t$this->assertArrayHasKey( 'registered_date_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'registered_since', $properties );\n\t\t$this->assertArrayHasKey( 'password', $properties );\n\t\t$this->assertArrayHasKey( 'roles', $properties );\n\t\t$this->assertArrayHasKey( 'member_types', $properties );\n\t\t$this->assertArrayHasKey( 'xprofile', $properties );\n\t\t$this->assertArrayHasKey( 'friendship_status', $properties );\n\t\t$this->assertArrayHasKey( 'friendship_status_slug', $properties );\n\t\t$this->assertArrayHasKey( 'last_activity', $properties );\n\t\t$this->assertArrayHasKey( 'latest_update', $properties );\n\t\t$this->assertArrayHasKey( 'total_friend_count', $properties );\n\t}\n\n\t/**\n\t * @group get_item\n\t * @group item_schema\n\t */\n\tpublic function test_get_item_schema_member_types_enum() {\n\t\t$expected = array( 'foo', 'bar' );\n\n\t\tforeach ( $expected as $type ) {\n\t\t\tbp_register_member_type( $type );\n\t\t}\n\n\t\t// Re-initialize the controller to cache-bust schemas from prior test runs.\n\t\t$GLOBALS['wp_rest_server']->override_by_default = true;\n\t\t$controller                                     = new BP_REST_Members_Endpoint();\n\t\t$controller->register_routes();\n\t\t$GLOBALS['wp_rest_server']->override_by_default = false;\n\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertArrayHasKey( 'member_types', $properties );\n\t\t$this->assertEquals( array_values( $properties['member_types']['enum'] ), $expected );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', self::$user ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn bp_update_user_meta( $data->id, '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_get_user_meta( $data['id'], '_' . $attribute, true );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields() {\n\t\t$this->skipWithMultisite();\n\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'members', 'foo_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Members single item Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$this->allow_user_to_manage_multisite();\n\t\t$expected = 'bar_value';\n\n\t\t$params = array(\n\t\t\t'password'   => 'testpassword',\n\t\t\t'email'      => 'test@example.com',\n\t\t\t'user_login' => 'testuser',\n\t\t\t'name'       => 'Test User',\n\t\t\t'foo_field'  => $expected,\n\t\t);\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( $params );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $create_data['foo_field'] );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $create_data['id'] ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $get_data['foo_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_update_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'members', 'bar_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Members single item Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$u = static::factory()->user->create( array(\n\t\t\t'email' => 'test@example.com',\n\t\t\t'name'  => 'User Name',\n\t\t) );\n\t\t$expected = 'foo_value';\n\n\t\t$this->allow_user_to_manage_multisite();\n\n\t\t// PUT\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $u ) );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$request->set_body_params( array( 'bar_field' => 'foo_value' ) );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$update_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $update_data['bar_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/membership/test-group-membership-controller.php",
    "content": "<?php\n/**\n * Group Membership Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group group-membership\n */\nclass BP_Test_REST_Group_Membership_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $group_id;\n\tprotected $server;\n\tprotected $search_terms;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Group_Membership_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->groups->id . '/';\n\t\t$this->user         = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\t$this->group_id = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test',\n\t\t\t'description' => 'Group Description',\n\t\t\t'creator_id'  => $this->user,\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url . '(?P<group_id>[\\d]+)/members';\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 2, $routes[ $endpoint ] );\n\n\t\t// Single.\n\t\t$single_endpoint = $endpoint . '/(?P<user_id>[\\d]+)';\n\n\t\t$this->assertArrayHasKey( $single_endpoint, $routes );\n\t\t$this->assertCount( 2, $routes[ $single_endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 2, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 1, $headers['X-WP-TotalPages'] );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$u_ids = wp_list_pluck( $all_data, 'id' );\n\n\t\t// Check results.\n\t\t$this->assertCount( 2, $u_ids );\n\t\t$this->assertEqualSets( [ $u1, $u2 ], $u_ids );\n\t\t$this->assertNotContains( $u3, $u_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_by_specific_group_role() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator' => $u1,\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t// Promote $u2 to a moderator\n\t\tadd_filter( 'bp_is_item_admin', '__return_true' );\n\n\t\t$member_object = new BP_Groups_Member( $u2, $g1 );\n\t\t$member_object->promote( 'mod' );\n\n\t\tremove_filter( 'bp_is_item_admin', '__return_true' );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' );\n\t\t$request->set_query_params( array(\n\t\t\t'roles' => array( 'mod' ),\n\t\t) );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$u_ids = wp_list_pluck( $all_data, 'id' );\n\n\t\t// Check results.\n\t\t$this->assertCount( 1, $u_ids );\n\t\t$this->assertEqualSets( [ $u2 ], $u_ids );\n\t\t$this->assertNotContains( $u1, $u_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator' => $u1,\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_paginated_items() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\t\t$u5 = static::factory()->user->create();\n\t\t$u6 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2, $u3, $u4, $u5, $u6 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' );\n\t\t$request->set_query_params( array(\n\t\t\t'page'     => 2,\n\t\t\t'per_page' => 3,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 6, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 2, $headers['X-WP-TotalPages'] );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$u_ids = wp_list_pluck( $all_data, 'id' );\n\n\t\t// Check results.\n\t\t$this->assertCount( 3, $u_ids );\n\t\t$this->assertEqualSets( [ $u4, $u5, $u6 ], $u_ids );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_no_search_terms() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$g1 = $this->bp::factory()->group->create();\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$member_object = new BP_Groups_Member( $u1, $g1 );\n\t\t$member_object->promote( 'admin' );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\tadd_filter( 'bp_rest_group_members_get_items_query_args', array( $this, 'group_members_query_args' ) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' );\n\n\t\t$this->server->dispatch( $request );\n\n\t\tremove_filter( 'bp_rest_group_members_get_items_query_args', array( $this, 'group_members_query_args' ) );\n\n\t\t$this->assertFalse( $this->search_terms );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_has_search_terms() {\n\t\t$u1 = static::factory()->user->create( array(\n\t\t\t'user_nicename' => 'foo',\n\t\t) );\n\n\t\t$u2 = static::factory()->user->create( array(\n\t\t\t'user_nicename' => 'foo bar',\n\t\t) );\n\n\t\t$g1 = $this->bp::factory()->group->create();\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$member_object = new BP_Groups_Member( $u1, $g1 );\n\t\t$member_object->promote( 'admin' );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\tadd_filter( 'bp_rest_group_members_get_items_query_args', array( $this, 'group_members_query_args' ) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' );\n\t\t$request->set_param( 'search', 'bar' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tremove_filter( 'bp_rest_group_members_get_items_query_args', array( $this, 'group_members_query_args' ) );\n\n\t\t$this->assertTrue( 'bar' === $this->search_terms );\n\n\t\t$all_data = $response->get_data();\n\t\t$results = wp_list_pluck( $all_data, 'id' );\n\n\t\t$this->assertCount( 1, $results );\n\t\t$this->assertSame( $u2, $results[0] );\n\t}\n\n\t// Filter used to catch the search_terms query argument.\n\tpublic function group_members_query_args( $args ) {\n\t\tif ( isset( $args['search_terms'] ) ) {\n\t\t\t$this->search_terms = $args['search_terms'];\n\t\t}\n\n\t\treturn $args;\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->markTestSkipped( 'This endpoint does not have a get_item meethod.' );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$u = static::factory()->user->create();\n\t\t$g = $this->bp::factory()->group->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url . $g . '/members' );\n\t\t$request->set_query_params( array( 'user_id' => $u ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data = reset( $all_data );\n\t\t$this->assertTrue( $data['is_confirmed'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_as_admin() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'administrator' ) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url . $this->group_id . '/members' );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u,\n\t\t) );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $this->group_id );\n\n\t\t$this->check_user_data( $user, $data, $member_object, 'edit' );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_member_can_add_himself_to_public_group() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url . $this->group_id . '/members' );\n\n\t\t// This usually would be 'edit', but we are testing a public group.\n\n\t\t$request->set_query_params( array( 'user_id' => $u ) );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\tforeach ( $all_data as $data ) {\n\t\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t\t$member_object = new BP_Groups_Member( $user->ID, $this->group_id );\n\n\t\t\t$this->check_user_data( $user, $data, $member_object, 'edit' );\n\t\t}\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_member_can_not_add_himself_to_private_group() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'private',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url . $g1 . '/members' );\n\t\t$request->set_query_params( array( 'user_id' => $u ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_failed_to_join', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_member_can_not_add_himself_to_hidden_group() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'status' => 'hidden',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url . $g1 . '/members' );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_failed_to_join', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_member_cannot_add_others_to_public_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url . $this->group_id . '/members' );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u2,\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_failed_to_join', $response, 500 );\n\t}\n\n\t/**\n\t * Site admin can ban member.\n\t *\n\t * @group update_item\n\t * @group ban_member\n\t */\n\tpublic function test_update_item() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->populate_group_with_members( [ $u ], $this->group_id );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $this->group_id . '/members/' . $u  );\n\t\t$request->set_query_params( array( 'action' => 'ban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $u, $this->group_id );\n\n\t\t$this->assertTrue( $u === $user->ID );\n\t\t$this->assertTrue( (bool) $member_object->is_banned );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group ban_member\n\t */\n\tpublic function test_group_mod_can_not_ban_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Promote $u2 to a group mod.\n\t\t$member_object = new BP_Groups_Member( $u1, $g1 );\n\t\t$member_object->promote( 'mod' );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u3 );\n\t\t$request->set_query_params( array( 'action' => 'ban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_ban', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group ban_member\n\t */\n\tpublic function test_group_mod_can_not_ban_random_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Promote $u2 to a group mod.\n\t\t$member_object = new BP_Groups_Member( $u1, $g1 );\n\t\t$member_object->promote( 'mod' );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u4 );\n\t\t$request->set_query_params( array( 'action' => 'ban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_ban', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group ban_member\n\t */\n\tpublic function test_group_admin_can_ban_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Promote $u2 to a group admin.\n\t\t$member_object = new BP_Groups_Member( $u2, $g1 );\n\t\t$member_object->promote( 'admin' );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array( 'action' => 'ban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u1 === $user->ID );\n\t\t$this->assertTrue( (bool) $member_object->is_banned );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group ban_member\n\t */\n\tpublic function test_group_admin_can_not_ban_random_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u4 );\n\t\t$request->set_query_params( array( 'action' => 'ban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_not_member', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_site_admin_can_unban_member_from_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Ban $u1.\n\t\t$member_object = new BP_Groups_Member( $u1, $g1 );\n\t\t$member_object->ban();\n\n\t\t$this->assertTrue( (bool) $member_object->is_banned );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array( 'action' => 'unban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u1 === $user->ID );\n\t\t$this->assertFalse( (bool) $member_object->is_banned );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_site_admin_can_not_unban_random_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$u4 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u4 );\n\t\t$request->set_query_params( array( 'action' => 'unban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertFalse( groups_is_user_member( $user->ID, $g1 ) );\n\t\t$this->assertTrue( $u4 === $user->ID );\n\t\t$this->assertFalse( (bool) $member_object->is_banned );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_group_admin_can_unban_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Promote $u2 to a group admin.\n\t\t$member_object = new BP_Groups_Member( $u2, $g1 );\n\t\t$member_object->promote( 'admin' );\n\n\t\t// Ban $u1.\n\t\t$member_object = new BP_Groups_Member( $u1, $g1 );\n\t\t$member_object->ban();\n\n\t\t$this->assertTrue( (bool) $member_object->is_banned );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array( 'action' => 'unban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u1 === $user->ID );\n\t\t$this->assertFalse( (bool) $member_object->is_banned );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_group_mod_can_not_unban_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Promote $u2 to a group mod.\n\t\t$member_object = new BP_Groups_Member( $u2, $g1 );\n\t\t$member_object->promote( 'mod' );\n\n\t\t// Ban $u1.\n\t\t$member_object = new BP_Groups_Member( $u1, $g1 );\n\t\t$member_object->ban();\n\n\t\t$this->assertTrue( (bool) $member_object->is_banned );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array( 'action' => 'unban' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_unban', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group promote_member\n\t */\n\tpublic function test_site_admin_can_promote_member_to_mod() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->populate_group_with_members( [ $u ], $this->group_id );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $this->group_id . '/members/' . $u );\n\t\t$request->set_query_params( array(\n\t\t\t'action' => 'promote',\n\t\t\t'role'   => 'mod',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $this->group_id );\n\n\t\t$this->assertTrue( $u === $user->ID );\n\t\t$this->assertTrue( (bool) $member_object->is_mod );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group promote_member\n\t */\n\tpublic function test_group_admin_can_promote_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array(\n\t\t\t'action' => 'promote',\n\t\t\t'role'   => 'mod',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = reset( $all_data );\n\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u1 === $user->ID );\n\t\t$this->assertTrue( (bool) $member_object->is_mod );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group promote_member\n\t */\n\tpublic function test_member_can_not_promote_other_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array(\n\t\t\t'action' => 'promote',\n\t\t\t'role'   => 'mod',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group promote_member\n\t */\n\tpublic function test_group_mods_can_not_promote_members() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u1 ) );\n\n\t\t// Promote $u2 to a mod.\n\t\t$this->bp::add_user_to_group( $u2, $g1, array( 'is_mod' => true ) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array(\n\t\t\t'action' => 'promote',\n\t\t\t'role'   => 'mod',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group promote_member\n\t */\n\tpublic function test_group_mod_can_not_promote_himself() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u1 ) );\n\n\t\t// Promote $u1 to a mod.\n\t\t$this->bp::add_user_to_group( $u1, $g1, array( 'is_mod' => true ) );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array(\n\t\t\t'action' => 'promote',\n\t\t\t'role'   => 'admin',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_site_admin_can_demote_group_admin_to_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Promote $u3 to an admin.\n\t\t$member_object = new BP_Groups_Member( $u3, $g1 );\n\t\t$member_object->promote( 'admin' );\n\n\t\t$this->assertTrue( (bool) $member_object->is_admin );\n\n\t\t// Site admin.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data      = $response->get_data();\n\t\t$data          = $all_data[0];\n\t\t$user          = bp_rest_get_user( $data['id'] );\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u2 === $user->ID );\n\t\t$this->assertFalse( (bool) $member_object->is_mod );\n\t\t$this->assertFalse( (bool) $member_object->is_admin );\n\t\t$this->assertTrue( (bool) groups_is_user_member( $u2, $g1 ) );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_site_admin_can_not_demote_the_only_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Site admin.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_site_admin_can_not_demote_himself() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Site admin.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $this->user );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_site_admin_can_demote_group_admins() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Promote $u2 to an admin.\n\t\t$member_object = new BP_Groups_Member( $u2, $g1 );\n\t\t$member_object->promote( 'admin' );\n\n\t\t// Promote $u3 to an admin.\n\t\t$member_object = new BP_Groups_Member( $u3, $g1 );\n\t\t$member_object->promote( 'admin' );\n\n\t\t$this->assertTrue( (bool) $member_object->is_admin );\n\n\t\t// Site admin.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$user = bp_rest_get_user( $data[0]['id'] );\n\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u2 === $user->ID );\n\t\t$this->assertFalse( (bool) $member_object->is_mod );\n\t\t$this->assertFalse( (bool) $member_object->is_admin );\n\t\t$this->assertTrue( (bool) groups_is_user_member( $u2, $g1 ) );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_site_admin_can_demote_group_mods() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2, $u3 ], $g1 );\n\n\t\t// Promote $u2 to an admin.\n\t\t$member_object = new BP_Groups_Member( $u2, $g1 );\n\t\t$member_object->promote( 'mod' );\n\n\t\t$this->assertTrue( (bool) $member_object->is_mod );\n\n\t\t// Site admin.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$user = bp_rest_get_user( $data[0]['id'] );\n\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u2 === $user->ID );\n\t\t$this->assertFalse( (bool) $member_object->is_mod );\n\t\t$this->assertFalse( (bool) $member_object->is_admin );\n\t\t$this->assertTrue( (bool) groups_is_user_member( $u2, $g1 ) );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_site_admin_can_not_demote_already_group_members() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2, $u3 ], $g1 );\n\n\t\t// Promote $u2 to an admin.\n\t\t$member_object = new BP_Groups_Member( $u2, $g1 );\n\t\t$member_object->promote( 'mod' );\n\n\t\t$this->assertTrue( (bool) $member_object->is_mod );\n\n\t\t// Site admin.\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_failed_to_demote', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_group_admin_can_demote_another_group_admin_to_mod() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$group_member = new BP_Groups_Member( $u2, $g1 );\n\t\t$group_member->promote( 'admin' );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$request->set_query_params( array(\n\t\t\t'action' => 'demote',\n\t\t\t'role'   => 'mod',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$user = bp_rest_get_user( $data[0]['id'] );\n\n\t\t$member_object = new BP_Groups_Member( $user->ID, $g1 );\n\n\t\t$this->assertTrue( $u2 === $user->ID );\n\t\t$this->assertTrue( (bool) $member_object->is_mod );\n\t\t$this->assertFalse( (bool) $member_object->is_admin );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_group_admin_can_not_demote_himself() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_group_admin_can_not_demote_already_group_members() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_failed_to_demote', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_member_can_not_demote_another_member() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group demote_member\n\t */\n\tpublic function test_member_can_not_demote_himself() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u3 );\n\t\t$request->set_query_params( array( 'action' => 'demote' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t * @group promote_member\n\t */\n\tpublic function test_update_item_invalid_group_id() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/members/' . $u );\n\t\t$request->set_query_params( array(\n\t\t\t'action' => 'promote',\n\t\t\t'role'   => 'mod',\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'PUT', $this->endpoint_url . $this->group_id . '/members/0' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, 401 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u3,\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$user = bp_rest_get_user( $all_data['previous']['id'] );\n\t\t$this->assertFalse( groups_is_user_member( $user->ID, $g1 ) );\n\t\t$this->assertSame( $u1, $user->ID );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_member_can_remove_himself_from_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u3,\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$user = bp_rest_get_user( $all_data['previous']['id'] );\n\t\t$this->assertFalse( groups_is_user_member( $user->ID, $g1 ) );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_banned_member_can_not_remove_himself_from_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u3,\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$group_member = new BP_Groups_Member( $u1, $g1 );\n\t\t$group_member->ban();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_member_can_not_remove_others_from_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u3,\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_group_admin_can_remove_member_from_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u3, // <- group admin.\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$user = bp_rest_get_user( $all_data['previous']['id'] );\n\t\t$this->assertFalse( groups_is_user_member( $user->ID, $g1 ) );\n\t\t$this->assertSame( $u1, $user->ID );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_group_admin_can_remove_himself_from_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u2, // <- group admin.\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u3 ], $g1 );\n\n\t\t// Another group admin.\n\t\t$group_member = new BP_Groups_Member( $u3, $g1 );\n\t\t$group_member->promote( 'admin' );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$user = bp_rest_get_user( $all_data['previous']['id'] );\n\t\t$this->assertFalse( groups_is_user_member( $user->ID, $g1 ) );\n\t\t$this->assertSame( $u2, $user->ID );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_last_group_admin_can_not_remove_himself_from_group() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u2, // <- group admin.\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1 ], $g1 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_group_admin_can_remove_another_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u1, // <- group admin.\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u2, $u3 ], $g1 );\n\n\t\t$group_member = new BP_Groups_Member( $u3, $g1 );\n\t\t$group_member->promote( 'admin' );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$user = bp_rest_get_user( $all_data['previous']['id'] );\n\t\t$this->assertFalse( groups_is_user_member( $user->ID, $g1 ) );\n\t\t$this->assertSame( $u1, $user->ID );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_site_admin_can_not_remove_himself_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u1, // <- group admin.\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u2, $u3 ], $g1 );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $this->user );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_failed_to_remove', $response, 500 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_site_admin_can_remove_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u1, // <- group admin.\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u2, $u3 ], $g1 );\n\n\t\t$group_member = new BP_Groups_Member( $u3, $g1 );\n\t\t$group_member->promote( 'admin' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$user = bp_rest_get_user( $all_data['previous']['id'] );\n\t\t$this->assertFalse( groups_is_user_member( $user->ID, $g1 ) );\n\t\t$this->assertSame( $u1, $user->ID );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_site_admin_can_not_remove_last_group_admin() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$g1 = $this->bp::factory()->group->create( array(\n\t\t\t'creator_id' => $u1, // <- group admin.\n\t\t) );\n\n\t\t$this->populate_group_with_members( [ $u1, $u2 ], $g1 );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * Add member to the group.\n\t */\n\tprotected function populate_group_with_members( $members, $group_id ) {\n\t\tforeach ( $members as $member_id ) {\n\t\t\t$this->bp::add_user_to_group( $member_id, $group_id );\n\t\t}\n\t}\n\n\tprotected function check_user_data( $user, $data, $member_object, $context = 'view' ) {\n\t\t$this->assertEquals( $user->ID, $data['id'] );\n\t\t$this->assertEquals( $user->display_name, $data['name'] );\n\t\t$this->assertEquals( $user->user_login, $data['user_login'] );\n\t\t$this->assertArrayHasKey( 'avatar_urls', $data );\n\t\t$this->assertArrayHasKey( 'thumb', $data['avatar_urls'] );\n\t\t$this->assertArrayHasKey( 'full', $data['avatar_urls'] );\n\t\t$this->assertArrayHasKey( 'member_types', $data );\n\t\t$this->assertEquals(\n\t\t\tbp_members_get_user_url( $data['id'] ),\n\t\t\t$data['link']\n\t\t);\n\n\t\tif ( 'view' === $context ) {\n\t\t\t$this->assertArrayNotHasKey( 'roles', $data );\n\t\t\t$this->assertArrayNotHasKey( 'capabilities', $data );\n\t\t\t$this->assertArrayNotHasKey( 'extra_capabilities', $data );\n\t\t\t$this->assertArrayNotHasKey( 'registered_date', $data );\n\t\t}\n\n\t\t$this->assertArrayHasKey( 'xprofile', $data );\n\n\t\t// Checking extra.\n\t\t$this->assertEquals( $member_object->is_mod, (bool) $data['is_mod'] );\n\t\t$this->assertEquals( $member_object->is_admin, (bool) $data['is_admin'] );\n\t\t$this->assertEquals( $member_object->is_banned, (bool) $data['is_banned'] );\n\t\t$this->assertEquals( $member_object->is_confirmed, (bool) $data['is_confirmed'] );\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $member_object->date_modified ), $data['date_modified_gmt'] );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$this->skipWithMultisite();\n\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url . $this->group_id . '/members' );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 27, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'avatar_urls', $properties );\n\t\t$this->assertArrayHasKey( 'capabilities', $properties );\n\t\t$this->assertArrayHasKey( 'extra_capabilities', $properties );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'group_id', $properties );\n\t\t$this->assertArrayHasKey( 'link', $properties );\n\t\t$this->assertArrayHasKey( 'name', $properties );\n\t\t$this->assertArrayHasKey( 'mention_name', $properties );\n\t\t$this->assertArrayHasKey( 'registered_date', $properties );\n\t\t$this->assertArrayHasKey( 'registered_date_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'registered_since', $properties );\n\t\t$this->assertArrayHasKey( 'password', $properties );\n\t\t$this->assertArrayHasKey( 'roles', $properties );\n\t\t$this->assertArrayHasKey( 'xprofile', $properties );\n\t\t$this->assertArrayHasKey( 'friendship_status', $properties );\n\t\t$this->assertArrayHasKey( 'friendship_status_slug', $properties );\n\t\t$this->assertArrayHasKey( 'last_activity', $properties );\n\t\t$this->assertArrayHasKey( 'latest_update', $properties );\n\t\t$this->assertArrayHasKey( 'total_friend_count', $properties );\n\n\t\t// Extra fields.\n\t\t$this->assertArrayHasKey( 'is_mod', $properties );\n\t\t$this->assertArrayHasKey( 'is_admin', $properties );\n\t\t$this->assertArrayHasKey( 'is_banned', $properties );\n\t\t$this->assertArrayHasKey( 'is_confirmed', $properties );\n\t\t$this->assertArrayHasKey( 'date_modified', $properties );\n\t\t$this->assertArrayHasKey( 'date_modified_gmt', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url . $this->group_id . '/members' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'embed', 'edit',  ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/membership/test-group-membership-request-controller.php",
    "content": "<?php\n/**\n * Group Membership Request Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group group-membership-request\n */\nclass BP_Test_REST_Group_Membership_Request_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $group_id;\n\tprotected $g1admin;\n\tprotected $g1;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Group_Membership_Request_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->groups->id . '/membership-requests';\n\t\t$this->user         = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\t$this->group_id = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test',\n\t\t\t'description' => 'Group Description',\n\t\t\t'creator_id'  => $this->user,\n\t\t\t'status'      => 'private',\n\t\t) );\n\n\t\t// Create a group with a group admin that is not a site admin.\n\t\t$this->g1admin = static::factory()->user->create( array(\n\t\t\t'role'       => 'subscriber',\n\t\t\t'user_email' => 'sub@example.com',\n\t\t) );\n\t\t$this->g1 = $this->bp::factory()->group->create( array(\n\t\t\t'name'        => 'Group Test 1',\n\t\t\t'description' => 'Group Description 1',\n\t\t\t'status'      => 'private',\n\t\t\t'creator_id'  => $this->g1admin,\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// GET and CREATE.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// PUT, etc.\n\t\t$put_endpoint = $this->endpoint_url . '/(?P<request_id>[\\d]+)';\n\n\t\t$this->assertArrayHasKey( $put_endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $put_endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$u   = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2  = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u3  = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u2 ) );\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u3 ) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( 3 === count( $all_data ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$u   = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2  = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u3  = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u2 ) );\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u3 ) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_as_group_admin() {\n\t\t$u   = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2  = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\tgroups_send_membership_request( array( 'group_id' => $this->g1, 'user_id' => $u ) );\n\t\tgroups_send_membership_request( array( 'group_id' => $this->g1, 'user_id' => $u2 ) );\n\n\t\t$this->bp::set_current_user( $this->g1admin );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->g1,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( 2 === count( $all_data ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_as_requestor() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( 1 === count( $all_data ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_is_not_logged_in() {\n\t\t$this->bp::set_current_user( 0 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_has_no_access_to_group() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_cannot_get_items', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_has_no_access_to_user() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\tgroups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id' => $u,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_cannot_get_items', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_invalid_group() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => REST_TESTS_IMPOSSIBLY_HIGH_NUMBER,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/'. $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$accepted = groups_is_user_member( $u, $this->group_id );\n\t\t$this->assertFalse( $accepted );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$u          = static::factory()->user->create( array( 'role'       => 'subscriber' ) );\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/'. $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_user_is_not_logged_in() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( 0 );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/'. $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_membership_request() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_no_access() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_cannot_get_item', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'  => $u,\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $this->group_id === $all_data[0]['group_id'] && $u === $all_data[0]['user_id'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_as_subscriber() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'group_id' => $this->group_id,\n\t\t\t'user_id'  => $u,\n\t\t) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $this->group_id === $all_data[0]['group_id'] && $u === $all_data[0]['user_id'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_is_not_logged_in() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::set_current_user( 0 );\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'  => $u,\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_member() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'  => REST_TESTS_IMPOSSIBLY_HIGH_NUMBER,\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_invalid_group() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'  => $u,\n\t\t\t'group_id' => REST_TESTS_IMPOSSIBLY_HIGH_NUMBER,\n\t\t) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_an_already_group_member() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::add_user_to_group( $u, $this->group_id );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'  => $u,\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_cannot_create_item', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_fails_with_pending_request() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params( array(\n\t\t\t'user_id'  => $u,\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_duplicate_request', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $request_id );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$status = groups_is_user_member( $u, $this->group_id );\n\t\t$this->assertTrue( is_int( $status ) && $status > 0 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_as_group_admin() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->g1, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $this->g1admin );\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$status = groups_is_user_member( $u, $this->g1 );\n\t\t$this->assertTrue( is_int( $status ) && $status > 0 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_is_not_logged_in() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( 0 );\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_has_no_access() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_member_request_cannot_update_item', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $all_data['deleted'] );\n\t\t$this->assertEquals( $request_id, $all_data['previous']['id']);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_as_requestor() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $all_data['deleted'] );\n\t\t$this->assertEquals( $request_id, $all_data['previous']['id']);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_as_group_admin() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->g1, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $this->g1admin );\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertTrue( $all_data['deleted'] );\n\t\t$this->assertEquals( $request_id, $all_data['previous']['id']);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_is_not_logged_in() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->g1, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( 0 );\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_has_no_access() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$request_id = groups_send_membership_request( array( 'group_id' => $this->group_id, 'user_id' => $u ) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $request_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_group_membership_requests_cannot_delete_item', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 7, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'user_id', $properties );\n\t\t$this->assertArrayHasKey( 'date_modified', $properties );\n\t\t$this->assertArrayHasKey( 'date_modified_gmt', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/messages/test-controller.php",
    "content": "<?php\n\n/**\n * Messages Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group messages\n */\nclass BP_Test_REST_Messages_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Messages_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->messages->id;\n\t\t$this->user         = static::factory()->user->create( array( 'role' => 'administrator' ) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url;\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 2, $routes[ $endpoint ] );\n\n\t\t// Single.\n\t\t$single_endpoint = $endpoint . '/(?P<id>[\\d]+)';\n\n\t\t$this->assertArrayHasKey( $single_endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $single_endpoint ] );\n\n\t\t// Starred.\n\t\t$starred_endpoint = $endpoint . '/' . bp_get_messages_starred_slug() . '/(?P<id>[\\d]+)';\n\n\t\t$this->assertArrayHasKey( $starred_endpoint, $routes );\n\t\t$this->assertCount( 1, $routes[ $starred_endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::factory()->message->create( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::factory()->message->create( array(\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Fooo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'user_id', $u1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data  = $response->get_data();\n\t\t$a_ids = wp_list_pluck( $data, 'id' );\n\n\t\t$a_ids = wp_list_pluck( $data, 'id' );\n\n\t\t$this->assertCount( 1, $a_ids );\n\t\t$this->assertCount( 1, $data[0]['messages'] );\n\n\t\t// Check the thread data for the requested user id => `$u1` (see at line 74 ^^).\n\t\t$this->check_thread_data( $this->endpoint->get_thread_object( $data[0]['id'], $u1 ), $data[0] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_and_paginate_messages_recipients() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t$thread = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::factory()->message->create( array(\n\t\t\t'thread_id'  => $thread->thread_id,\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Fooo',\n\t\t) );\n\n\t\t$thread2 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u3 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::factory()->message->create( array(\n\t\t\t'thread_id'  => $thread2->thread_id,\n\t\t\t'sender_id'  => $u3,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Fooo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'user_id'             => $u1,\n\t\t\t\t'messages_per_page'   => 1,\n\t\t\t\t'recipients_per_page' => 1,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t// Messages.\n\t\t$this->assertCount( 1, $all_data[0]['messages'] );\n\t\t$this->assertCount( 1, $all_data[1]['messages'] );\n\n\t\t// Recipients.\n\t\t$this->assertCount( 1, $all_data[0]['recipients'] );\n\t\t$this->assertCount( 1, $all_data[1]['recipients'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m->thread_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$data = current( $all_data );\n\t\t$this->check_thread_data( $this->endpoint->get_thread_object( $data['id'], $u2 ), $data );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_thread_messages_paginated() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t// create several messages.\n\t\t$this->bp::factory()->message->create_many( 10, array(\n\t\t\t'thread_id'  => $m->thread_id,\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'content'    => 'Bar',\n\t\t) );\n\n\t\t// create a reply.\n\t\t$message_id = $this->bp::factory()->message->create( array(\n\t\t\t'sender_id'  => $u2,\n\t\t\t'thread_id'  => $m->thread_id,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'content'    => 'Bar',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m->thread_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'messages_per_page', 1 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertEquals( 12, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 12, $headers['X-WP-TotalPages'] );\n\n\t\t$all_data = current( $response->get_data() );\n\n\t\t$this->assertCount( 1, $all_data['messages'] );\n\t\t$this->assertSame( $m->thread_id, $all_data['messages'][0]['thread_id'] );\n\t\t$this->assertSame( $message_id, $all_data['messages'][0]['id'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_admin_access() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m->thread_id );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'user_id', $u2 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$data = current( $all_data );\n\n\t\t$this->assertFalse( isset( $data['message']['raw'] ) );\n\t\t$this->assertFalse( isset( $data['excerpt']['raw'] ) );\n\t\t$this->assertFalse( isset( $data['subject']['raw'] ) );\n\t\t$this->assertSame( 'Foo', $data['subject']['rendered'] );\n\n\t\t$message = $data['messages'][0];\n\n\t\t$this->assertSame( $m->id, $message['id'] );\n\t\t$this->assertFalse( isset( $message['message']['raw'] ) );\n\t\t$this->assertFalse( isset( $message['subject']['raw'] ) );\n\n\t\t$this->assertTrue( isset( $message['message']['rendered'] ) );\n\t\t$this->assertTrue( isset( $message['subject']['rendered'] ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_edit_context() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m->thread_id );\n\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_param( 'user_id', $u2 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$data = current( $all_data );\n\n\t\t$this->assertTrue( isset( $data['message']['raw'] ) );\n\t\t$this->assertTrue( isset( $data['excerpt']['raw'] ) );\n\t\t$this->assertTrue( isset( $data['subject']['raw'] ) );\n\t\t$this->assertSame( 'Foo', $data['subject']['raw'] );\n\n\t\t$message = $data['messages'][0];\n\n\t\t$this->assertSame( $m->id, $message['id'] );\n\t\t$this->assertTrue( isset( $message['message']['raw'] ) );\n\t\t$this->assertTrue( isset( $message['subject']['raw'] ) );\n\n\t\t$this->assertTrue( isset( $message['message']['rendered'] ) );\n\t\t$this->assertTrue( isset( $message['subject']['rendered'] ) );\n\t\t$this->assertSame( 'Foo', $message['subject']['raw'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_user_with_no_access() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m->thread_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t\t$this->assertSame( 403, $response->get_status() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_user_is_not_logged_in() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\tstatic::factory()->user->create();\n\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m->thread_id );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t\t$this->assertSame( 401, $response->get_status() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'sender_id'  => $this->user,\n\t\t\t\t'recipients' => [ $u ],\n\t\t\t\t'subject'    => 'Foo',\n\t\t\t\t'message'    => 'Content',\n\t\t\t)\n\t\t);\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$data = current( $all_data );\n\t\t$this->check_thread_data( $this->endpoint->get_thread_object( $data['id'] ), $data );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_is_not_logged_in() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'sender_id'  => $this->user,\n\t\t\t\t'recipients' => [ $u ],\n\t\t\t\t'subject'    => 'Foo',\n\t\t\t\t'message'    => 'Content',\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_no_content() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'sender_id'  => $this->user,\n\t\t\t\t'recipients' => [ static::factory()->user->create() ],\n\t\t\t\t'subject'    => 'Foo',\n\t\t\t)\n\t\t);\n\n\t\t$this->assertErrorResponse(\n\t\t\t'rest_missing_callback_param',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\t400\n\t\t);\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_no_receipts() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'sender_id' => $this->user,\n\t\t\t\t'subject'   => 'Foo',\n\t\t\t\t'message'   => 'Content',\n\t\t\t)\n\t\t);\n\n\t\t$this->assertErrorResponse(\n\t\t\t'rest_missing_callback_param',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\t400\n\t\t);\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $m->thread_id ) );\n\t\t$request->set_param( 'read', true );\n\t\t$request->set_param( 'user_id', $u2 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = current( $all_data );\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertFalse( (bool) $data['unread_count'] );\n\t\t$this->assertFalse( (bool) $data['recipients'][0]['unread_count'] );\n\t\t$this->assertFalse( (bool) $data['recipients'][1]['unread_count'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_thread_to_unread() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t// Update to read.\n\t\tmessages_mark_thread_read( $m->thread_id, $u2 );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $m->thread_id ) );\n\t\t$request->set_param( 'unread', true );\n\t\t$request->set_param( 'user_id', $u2 );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$data     = current( $all_data );\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertTrue( (bool) $data['unread_count'] );\n\n\t\tforeach ( $data['recipients'] as $recipient ) {\n\t\t\tif ( $recipient['user_id'] === $u1 ) {\n\t\t\t\t$this->assertFalse( (bool) $recipient['unread_count'] );\n\t\t\t} else {\n\t\t\t\t$this->assertTrue( (bool) $recipient['unread_count'] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_is_not_logged_in() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $m->thread_id ) );\n\n\t\t$this->assertErrorResponse(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\trest_authorization_required_code()\n\t\t);\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_with_user_with_no_access() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $m->thread_id ) );\n\n\t\t$this->assertErrorResponse(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\trest_authorization_required_code()\n\t\t);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $m->thread_id ) );\n\t\t$request->set_query_params( array( 'user_id' => $u2 ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertTrue( $data['deleted'] );\n\t\t$this->assertTrue( $data['previous']['subject']['rendered'] === 'Foo' );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_admin_access() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $m->thread_id );\n\t\t$request->set_query_params( array( 'user_id' => $u2 ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertTrue( $data['deleted'] );\n\t\t$this->assertTrue( $data['previous']['subject']['rendered'] === 'Foo' );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_with_user_with_no_access() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $m->thread_id );\n\n\t\t$this->assertErrorResponse(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\trest_authorization_required_code()\n\t\t);\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_is_not_logged_in() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'DELETE', $this->endpoint_url . '/' . $m );\n\n\t\t$this->assertErrorResponse(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\trest_authorization_required_code()\n\t\t);\n\t}\n\n\t/**\n\t * @group starred\n\t */\n\tpublic function test_get_starred_items() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t// Init another thread.\n\t\t$m2_id = $this->bp::factory()->message->create( array(\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Taz',\n\t\t) );\n\n\t\t// Create a reply.\n\t\t$r1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'thread_id'  => $m1->thread_id,\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'content'    => 'Bar',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\tbp_messages_star_set_action( array(\n\t\t\t'user_id'    => $u1,\n\t\t\t'message_id' => $r1->id,\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'user_id' => $u1,\n\t\t\t\t'box'     => 'starred',\n\t\t\t)\n\t\t);\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$threads  = wp_list_pluck( $data, 'id' );\n\t\t$this->assertNotContains( $m2_id, $threads );\n\t\t$this->assertContains( $m1->thread_id, $threads );\n\n\t\t$result = reset( $data );\n\t\t$this->assertNotEmpty( $result['starred_message_ids'] );\n\t\t$this->assertContains( $r1->id, $result['starred_message_ids'] );\n\t}\n\n\t/**\n\t * @group starred\n\t */\n\tpublic function test_update_starred_add_star() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t// Create a reply.\n\t\t$r1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'thread_id'  => $m1->thread_id,\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'content'    => 'Bar',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . bp_get_messages_starred_slug() . '/' . $r1->id );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\t\t$data     = reset( $data );\n\n\t\t$this->assertTrue( $data['is_starred'] );\n\t}\n\n\t/**\n\t * @group starred\n\t */\n\tpublic function test_update_starred_remove_star() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\tbp_messages_star_set_action( array(\n\t\t\t'user_id'    => $u2,\n\t\t\t'message_id' => $m->id,\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . bp_get_messages_starred_slug() . '/' . $m->id );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = current( $response->get_data() );\n\n\t\t$this->assertFalse( $data['is_starred'] );\n\t}\n\n\t/**\n\t * @group starred\n\t */\n\tpublic function test_update_starred_user_is_not_logged_in() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . bp_get_messages_starred_slug() . '/' . $m->id );\n\n\t\t$this->assertErrorResponse(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\trest_authorization_required_code()\n\t\t);\n\t}\n\n\t/**\n\t * @group starred\n\t */\n\tpublic function test_update_starred_user_with_no_access() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . bp_get_messages_starred_slug() . '/' . $m->id );\n\n\t\t$this->assertErrorResponse(\n\t\t\t'bp_rest_authorization_required',\n\t\t\t$this->server->dispatch( $request ),\n\t\t\trest_authorization_required_code()\n\t\t);\n\t}\n\n\t/**\n\t * @group starred\n\t */\n\tpublic function test_update_starred_using_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . bp_get_messages_starred_slug() . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn bp_messages_update_meta( $data->id, '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_messages_get_meta( $data['id'], '_' . $attribute );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields_for_get_item() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'messages', 'taz_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Message Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$expected = 'boz_value';\n\t\tbp_messages_update_meta( $m1->id, '_taz_field', $expected );\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m1->thread_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\n\t\t$last_message = wp_list_filter( $get_data[0]['messages'], array( 'id' => $get_data[0]['message_id'] ) );\n\t\t$last_message = reset( $last_message );\n\t\t$this->assertTrue( $expected === $last_message['taz_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields_for_created_thread() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'messages', 'foo_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Message Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'bar_value';\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'sender_id'  => $this->user,\n\t\t\t\t'recipients' => [ $u ],\n\t\t\t\t'subject'    => 'Foo',\n\t\t\t\t'message'    => 'Bar',\n\t\t\t\t'foo_field'  => $expected,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$last_message = wp_list_filter( $create_data[0]['messages'], array( 'id' => $create_data[0]['message_id'] ) );\n\t\t$last_message = reset( $last_message );\n\t\t$this->assertTrue( $expected === $last_message['foo_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields_for_created_reply() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'messages', 'bar_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Message Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u1 );\n\t\t$expected = 'foo_value';\n\n\t\t// POST a reply.\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'id'         => $m1->thread_id,\n\t\t\t\t'sender_id'  => $u1,\n\t\t\t\t'recipients' => array( $u2 ),\n\t\t\t\t'message'    => 'Taz',\n\t\t\t\t'bar_field'  => $expected,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\t\t$create_data = $response->get_data();\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$this->assertNotEmpty( $create_data );\n\n\t\t$last_message = wp_list_filter( $create_data[0]['messages'], array( 'id' => $create_data[0]['message_id'] ) );\n\t\t$last_message = reset( $last_message );\n\t\t$this->assertTrue( $expected === $last_message['bar_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields_for_last_message_updated() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'messages', 'boz_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Message Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Foo',\n\t\t) );\n\n\t\t$this->bp::factory()->message->create_and_get( array(\n\t\t\t'thread_id'  => $m1->thread_id,\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Bar',\n\t\t) );\n\n\t\t$this->bp::factory()->message->create_and_get( array(\n\t\t\t'thread_id'  => $m1->thread_id,\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Taz',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\t\t$expected = 'taz_value';\n\n\t\t// Update the last message.\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $m1->thread_id );\n\t\t$request->set_query_params( array( 'boz_field'  => $expected ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$update_data = $response->get_data();\n\t\t$this->assertNotEmpty( $update_data );\n\n\t\t$last_message = wp_list_filter( $update_data[0]['messages'], array( 'id' => $update_data[0]['message_id'] ) );\n\t\t$last_message = reset( $last_message );\n\t\t$this->assertTrue( $expected === $last_message['boz_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields_for_specific_message_updated() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'messages', 'top_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Message Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t// Init a thread.\n\t\t$m1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Top',\n\t\t) );\n\n\t\t$r1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'thread_id'  => $m1->thread_id,\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Up',\n\t\t) );\n\n\t\t$r1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'thread_id'  => $m1->thread_id,\n\t\t\t'sender_id'  => $u2,\n\t\t\t'recipients' => array( $u1 ),\n\t\t\t'subject'    => 'Upper',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\t\t$expected = 'up_value';\n\n\t\t// Update the last message.\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/' . $m1->thread_id );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'message_id' => $r1->id,\n\t\t\t\t'top_field'  => $expected,\n\t\t\t)\n\t\t);\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$update_data = $response->get_data();\n\t\t$specific_message = wp_list_filter( $update_data[0]['messages'], array( 'id' => $r1->id ) );\n\t\t$specific_message = reset( $specific_message );\n\t\t$this->assertTrue( $expected === $specific_message['top_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group prepare_recipient_for_response\n\t */\n\tpublic function test_prepare_prepare_recipient_for_response() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$u3 = static::factory()->user->create();\n\t\t$m  = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2, $u3 ),\n\t\t\t'subject'    => 'Foo',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m->thread_id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data   = $response->get_data();\n\t\t$recipients = $get_data[0]['recipients'];\n\n\t\tforeach( $recipients as $recipient ) {\n\t\t\t$user_id = $recipient['user_id'];\n\t\t\t$this->assertEquals( esc_url( bp_members_get_user_url( $user_id ) ), $recipient['user_link'] );\n\n\t\t\tforeach ( array( 'full', 'thumb' ) as $type ) {\n\t\t\t\t$expected['user_avatars'][ $type ] = bp_core_fetch_avatar(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'item_id' => $user_id ,\n\t\t\t\t\t\t'html'    => false,\n\t\t\t\t\t\t'type'    => $type,\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t\t$this->assertEquals( $expected['user_avatars'][ $type ], $recipient['user_avatars'][ $type ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @group prepare_links\n\t */\n\tpublic function test_prepare_add_links_to_response() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\t\t$m1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'sender_id'  => $u1,\n\t\t\t'recipients' => array( $u2 ),\n\t\t\t'subject'    => 'Bar',\n\t\t\t'content'    => 'Content',\n\t\t) );\n\n\t\t$r1 = $this->bp::factory()->message->create_and_get( array(\n\t\t\t'thread_id'  => $m1->thread_id,\n\t\t\t'sender_id'  => $u2,\n\t\t\t'content'    => 'Reply',\n\t\t) );\n\n\t\t$this->bp::set_current_user( $u2 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $m1->thread_id );\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_links = $response->get_data();\n\t\t$links     = $get_links[0]['_links'];\n\n\t\t$this->assertEquals( rest_url( $this->endpoint_url . '/' ), $links['collection'][0]['href'] );\n\t\t$this->assertEquals( rest_url( $this->endpoint_url . '/' . $m1->thread_id ), $links['self'][0]['href'] );\n\t\t$this->assertEquals( rest_url( $this->endpoint_url . '/' . bp_get_messages_starred_slug() . '/' . $m1->id ), $links[ $m1->id ][0]['href'] );\n\t\t$this->assertEquals( rest_url( $this->endpoint_url . '/' . bp_get_messages_starred_slug() . '/' . $r1->id ), $links[ $r1->id ][0]['href'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tprotected function check_thread_data( $thread, $data ) {\n\t\t$this->assertEquals( $thread->thread_id, $data['id'] );\n\t\t$this->assertEquals( $thread->last_message_id, $data['message_id'] );\n\t\t$this->assertEquals( $thread->last_sender_id, $data['last_sender_id'] );\n\t\t$this->assertEquals( apply_filters( 'bp_get_message_thread_subject', $thread->last_message_subject ), $data['subject']['rendered'] );\n\t\t$this->assertEquals( apply_filters( 'bp_get_message_thread_content', $thread->last_message_content ), $data['message']['rendered'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $thread->last_message_date, get_date_from_gmt( $thread->last_message_date ) ),\n\t\t\t$data['date']\n\t\t);\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $thread->last_message_date ), $data['date_gmt'] );\n\t\t$this->assertEquals( $thread->unread_count, $data['unread_count'] );\n\t\t$this->assertEquals( $thread->sender_ids, $data['sender_ids'] );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 13, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'message_id', $properties );\n\t\t$this->assertArrayHasKey( 'last_sender_id', $properties );\n\t\t$this->assertArrayHasKey( 'subject', $properties );\n\t\t$this->assertArrayHasKey( 'date', $properties );\n\t\t$this->assertArrayHasKey( 'date_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'unread_count', $properties );\n\t\t$this->assertArrayHasKey( 'sender_ids', $properties );\n\t\t$this->assertArrayHasKey( 'messages', $properties );\n\t\t$this->assertArrayHasKey( 'starred_message_ids', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/notifications/test-controller.php",
    "content": "<?php\n/**\n * Notifications Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group notifications\n */\nclass BP_Test_REST_Notifications_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $notification_id;\n\tprotected $server;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint        = new BP_REST_Notifications_Endpoint();\n\t\t$this->bp              = new BP_UnitTestCase();\n\t\t$this->endpoint_url    = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->notifications->id;\n\t\t$this->notification_id = $this->bp::factory()->notification->create();\n\t\t$this->user            = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\d]+)', $routes );\n\t\t$this->assertCount( 3, $routes[ $this->endpoint_url . '/(?P<id>[\\d]+)' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$notification_id = $this->bp::factory()->notification->create( array( 'user_id' => $this->user ) );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array( 'user_id' => $this->user ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $all_data );\n\t\t$this->assertSame( $notification_id, $all_data[0]['id'] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_admin_can_get_items_from_multiple_users() {\n\t\t$u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::factory()->notification->create( array( 'user_id' => $u1, ) );\n\t\t$this->bp::factory()->notification->create( array( 'user_id' => $u2, ) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array( 'user_ids' => array( $u1, $u2 ) ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertEqualSets(\n\t\t\tarray( $u1, $u2 ),\n\t\t\twp_list_pluck( $all_data, 'user_id' )\n\t\t);\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_user_can_not_get_items_from_multiple_users() {\n\t\t$u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\n\t\t$this->bp::factory()->notification->create( array( 'user_id' => $u1 ) );\n\t\t$this->bp::factory()->notification->create( array( 'user_id' => $u2 ) );\n\n\t\t$this->bp::set_current_user( $u3 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params( array( 'user_ids' => array( $u1, $u2 ) ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_cannot_see_notifications_from_others() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$notification = $this->endpoint->get_notification_object( $this->notification_id );\n\t\t$this->assertEquals( $this->notification_id, $notification->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_notification_data( $notification, $all_data[0] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_user_from_notification_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$notification_id = $this->bp::factory()->notification->create( array( 'user_id' => $this->user ) );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_query_params( array( '_embed' => 'user' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $this->server->response_to_data( $response, true )[0];\n\n\t\t$this->assertNotEmpty( $data['_embedded']['user'] );\n\n\t\t$embedded_user = current( $data['_embedded']['user'] );\n\n\t\t$this->assertNotEmpty( $embedded_user );\n\t\t$this->assertSame( $notification_id, $data['id'] );\n\t\t$this->assertSame( $this->user, $embedded_user['id'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_group_from_notification_item() {\n\t\t$group_id        = $this->bp::factory()->group->create();\n\t\t$notification_id = $this->bp::factory()->notification->create(\n\t\t\t$this->set_notification_data(\n\t\t\t\tarray(\n\t\t\t\t\t'component_name' => buddypress()->groups->id,\n\t\t\t\t\t'item_id'        => $group_id\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_query_params( array( '_embed' => 'group' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $this->server->response_to_data( $response, true )[0];\n\n\t\t$this->assertNotEmpty( $data['_embedded']['group'] );\n\n\t\t// Group single endpoint returns an array.\n\t\t// @todo update this when we change the endpoint to return an object only in v2.\n\t\t$embedded_group = current( current( $data['_embedded']['group'] ) );\n\n\t\t$this->assertNotEmpty( $embedded_group );\n\t\t$this->assertSame( $notification_id, $data['id'] );\n\t\t$this->assertSame( $group_id, $embedded_group['id'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_activity_from_notification_item() {\n\t\t$activity_id     = $this->bp::factory()->activity->create();\n\t\t$notification_id = $this->bp::factory()->notification->create(\n\t\t\t$this->set_notification_data(\n\t\t\t\tarray(\n\t\t\t\t\t'component_name' => buddypress()->activity->id,\n\t\t\t\t\t'item_id'        => $activity_id\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_query_params( array( '_embed' => 'activity' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $this->server->response_to_data( $response, true )[0];\n\n\t\t$this->assertNotEmpty( $data['_embedded']['activity'] );\n\n\t\t// Activity single endpoint returns an array.\n\t\t// @todo update this when we change the endpoint to return an object only in v2.\n\t\t$embedded_activity = current( current( $data['_embedded']['activity'] ) );\n\n\t\t$this->assertNotEmpty( $embedded_activity );\n\t\t$this->assertSame( $notification_id, $data['id'] );\n\t\t$this->assertSame( $activity_id, $embedded_activity['id'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_embedded_blog_from_notification_item() {\n\n\t\t// @todo investigate why bp_is_active( 'blogs' ) is failing for this test only\n\t\t// when testing on MU.\n\t\t$this->markTestSkipped();\n\n\t\t$blog_title = 'The Foo Bar Blog';\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$blog_id = $this->bp::factory()->blog->create(\n\t\t\tarray( 'title' => $blog_title )\n\t\t);\n\n\t\t$notification_id = $this->bp::factory()->notification->create(\n\t\t\t$this->set_notification_data(\n\t\t\t\tarray(\n\t\t\t\t\t'component_name' => buddypress()->blogs->id,\n\t\t\t\t\t'item_id'        => $blog_id\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_query_params( array( '_embed' => 'blog' ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $this->server->response_to_data( $response, true )[0];\n\n\t\t$this->assertNotEmpty( $data['_embedded']['blog'] );\n\n\t\t// Blog single endpoint returns an array.\n\t\t// @todo update this when we change the endpoint to return an object only in v2.\n\t\t$embedded_blog = current( current( $data['_embedded']['blog'] ) );\n\n\t\t$this->assertNotEmpty( $embedded_blog );\n\t\t$this->assertSame( $notification_id, $data['id'] );\n\t\t$this->assertSame( $blog_id, $embedded_blog['id'] );\n\t\t$this->assertSame( $blog_title, $embedded_blog['name'] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_user_not_logged_in() {\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_user_cannot_see_notification() {\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\t\t$u               = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_notification_data();\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_notification_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_rest_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_notification_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_notification_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_notification_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_cannot_create() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_notification_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_notification_data( [ 'is_new' => 0 ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$new_data = $response->get_data();\n\t\t$this->assertNotEmpty( $new_data );\n\n\t\t$n = $this->endpoint->get_notification_object( $new_data[0]['id'] );\n\t\t$this->assertEquals( $params['is_new'], $n->is_new );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_notification_data( [ 'is_new' => 0 ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_notification_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->notification_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_without_access() {\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_same_status() {\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_notification_data( [ 'is_new' => 1 ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_user_cannot_update_notification_status', $response, 500 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\t\t$notification    = $this->endpoint->get_notification_object( $notification_id );\n\n\t\t$this->assertEquals( $notification_id, $notification->id );\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_notification_data( $notification, $all_data['previous'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_notification_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->notification_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_without_access() {\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$notification = $this->endpoint->get_notification_object( $this->notification_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $notification->id ) );\n\t\t$request->set_query_params( array( 'context' => 'edit' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_notification_data( $notification, $all_data[0] );\n\t}\n\n\tprotected function check_notification_data( $notification, $data ) {\n\t\t$this->assertEquals( $notification->id, $data['id'] );\n\t\t$this->assertEquals( $notification->user_id, $data['user_id'] );\n\t\t$this->assertEquals( $notification->item_id, $data['item_id'] );\n\t\t$this->assertEquals( $notification->secondary_item_id, $data['secondary_item_id'] );\n\t\t$this->assertEquals( $notification->component_name, $data['component'] );\n\t\t$this->assertEquals( $notification->component_action, $data['action'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $notification->date_notified, get_date_from_gmt( $notification->date_notified ) ),\n\t\t\t$data['date']\n\t\t);\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $notification->date_notified ), $data['date_gmt'] );\n\t\t$this->assertEquals( $notification->is_new, $data['is_new'] );\n\t}\n\n\tprotected function set_notification_data( $args = array() ) {\n\t\treturn wp_parse_args( $args, array(\n\t\t\t'user_id' => $this->user,\n\t\t\t'is_new'  => 1,\n\t\t) );\n\t}\n\n\tprotected function check_update_notification_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\t\t$this->assertArrayNotHasKey( 'Location', $headers );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$group = $this->endpoint->get_notification_object( $data[0]['id'] );\n\t\t$this->check_notification_data( $group, $data[0] );\n\t}\n\n\tprotected function check_create_notification_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$notification = $this->endpoint->get_notification_object( $data[0]['id'] );\n\t\t$this->check_notification_data( $notification, $data[0] );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 9, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'item_id', $properties );\n\t\t$this->assertArrayHasKey( 'secondary_item_id', $properties );\n\t\t$this->assertArrayHasKey( 'user_id', $properties );\n\t\t$this->assertArrayHasKey( 'component', $properties );\n\t\t$this->assertArrayHasKey( 'action', $properties );\n\t\t$this->assertArrayHasKey( 'date', $properties );\n\t\t$this->assertArrayHasKey( 'date_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'is_new', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->notification_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn bp_notifications_update_meta( $data->id, '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_notifications_get_meta( $data['id'], '_' . $attribute );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'notifications', 'foo_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Notification Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'bar_value';\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_notification_data( array( 'foo_field' => $expected ) );\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $create_data[0]['foo_field'] );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $create_data[0]['id'] ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $get_data[0]['foo_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_update_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'notifications', 'bar_field', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'Notification Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t) );\n\n\t\t$notification_id = $this->bp::factory()->notification->create( $this->set_notification_data() );\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'foo_value';\n\n\t\t// Put\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $notification_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_notification_data( array( 'is_new' => 0, 'bar_field' => 'foo_value' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$update_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $update_data[0]['bar_field'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/signup/test-controller.php",
    "content": "<?php\n/**\n * Signup Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group signup\n */\nclass BP_Test_REST_Signup_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $signup_id;\n\tprotected $server;\n\tprotected $signup_allowed;\n\n\tpublic function set_up() {\n\t\tif ( is_multisite() ) {\n\t\t\t$this->signup_allowed = get_site_option( 'registration' );\n\t\t\tupdate_site_option( 'registration', 'all' );\n\t\t} else {\n\t\t\t$this->signup_allowed = bp_get_option( 'users_can_register' );\n\t\t\tbp_update_option( 'users_can_register', 1 );\n\t\t}\n\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Signup_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/signup';\n\t\t$this->user         = static::factory()->user->create(\n\t\t\tarray(\n\t\t\t\t'role'       => 'administrator',\n\t\t\t\t'user_email' => 'admin@example.com',\n\t\t\t\t'user_login' => 'admin_user',\n\t\t\t)\n\t\t);\n\n\t\tif ( is_multisite() ) {\n\t\t\tgrant_super_admin( $this->user );\n\t\t}\n\n\t\t$this->signup_id = $this->create_signup();\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function tear_down() {\n\t\tif ( is_multisite() ) {\n\t\t\tupdate_site_option( 'registration', $this->signup_allowed );\n\t\t} else {\n\t\t\tbp_update_option( 'users_can_register', $this->signup_allowed );\n\t\t}\n\n\t\tparent::tear_down();\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\w-]+)', $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url . '/(?P<id>[\\w-]+)' ] );\n\t\t$this->assertCount( 1, $routes[ $this->endpoint_url . '/activate/(?P<activation_key>[\\w-]+)' ] );\n\t\t$this->assertCount( 1, $routes[ $this->endpoint_url . '/resend' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$s1     = $this->create_signup();\n\t\t$signup = $this->endpoint->get_signup_object( $s1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_query_params( array( 'include' => $s1 ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->check_signup_data( $signup, $all_data[0] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_paginated_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$s1 = $this->create_signup();\n\t\t$s2 = $this->create_signup();\n\t\t$s3 = $this->create_signup();\n\t\t$s4 = $this->create_signup();\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'include' => array( $s1, $s2, $s3, $s4 ),\n\t\t\t\t'number'  => 2,\n\t\t\t)\n\t\t);\n\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$headers = $response->get_headers();\n\n\t\t$this->assertEquals( 4, $headers['X-WP-Total'] );\n\t\t$this->assertEquals( 2, $headers['X-WP-TotalPages'] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_unauthorized_user() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$signup = $this->endpoint->get_signup_object( $this->signup_id );\n\t\t$this->assertEquals( $this->signup_id, $signup->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $this->signup_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->check_signup_data( $signup, $all_data[0] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_invalid_signup_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%s', $this->signup_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_unauthorized_user() {\n\t\t$u = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%s', $this->signup_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\n\t\t$params = $this->set_signup_data();\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$signup = current( $response->get_data() );\n\n\t\t$this->assertSame( $signup['user_login'], $params['user_login'] );\n\t\t$this->assertSame( $signup['user_email'], $params['user_email'] );\n\t\t$this->assertTrue( ! isset( $signup['activation_key'] ) );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_signup_fields() {\n\t\t$g1 = $this->bp::factory()->xprofile_group->create();\n\n\t\t$f1 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'textbox',\n\t\t\t\t'name'           => 'field1',\n\t\t\t]\n\t\t);\n\n\t\t$f2 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'checkbox',\n\t\t\t\t'name'           => 'field2',\n\t\t\t]\n\t\t);\n\n\t\tbp_xprofile_update_field_meta( $f1, 'signup_position', 2 );\n\t\tbp_xprofile_update_field_meta( $f2, 'signup_position', 3 );\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 2',\n\t\t\t]\n\t\t);\n\n\t\t$fullname_field_id = bp_xprofile_fullname_field_id();\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\n\t\t$params = $this->set_signup_data(\n\t\t\tarray(\n\t\t\t\t'signup_field_data' => array(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => $f1,\n\t\t\t\t\t\t'value'      => 'Field 1 Value',\n\t\t\t\t\t\t'visibility' => 'public'\n\t\t\t\t\t),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => $f2,\n\t\t\t\t\t\t'value'      => 'Option 2, Option 1,',\n\t\t\t\t\t\t'visibility' => 'public'\n\t\t\t\t\t),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => $fullname_field_id,\n\t\t\t\t\t\t'value'      => 'New User',\n\t\t\t\t\t\t'visibility' => 'public',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$signup = current( $response->get_data() );\n\n\t\t$this->assertSame( $signup['user_email'], $params['user_email'] );\n\n\t\t// Check the textbox field.\n\t\t$this->assertSame( $signup['meta'][ 'field_' . $f1 ], $params['signup_field_data'][0]['value'] );\n\t\t$this->assertSame( $signup['meta'][ 'field_' . $f1 . '_visibility' ], $params['signup_field_data'][0]['visibility'] );\n\n\t\t// Check the checkbox field.\n\t\t$this->assertSame( $signup['meta'][ 'field_' . $f2 ], array_map( 'trim', explode( ', ', $params['signup_field_data'][1]['value'] ) ) );\n\t\t$this->assertSame( $signup['meta'][ 'field_' . $f2 . '_visibility' ], $params['signup_field_data'][1]['visibility'] );\n\n\t\t$field_ids = wp_parse_id_list( explode( ',', $signup['meta']['profile_field_ids'] ) );\n\n\t\t$this->assertCount( 3, $field_ids );\n\t\t$this->assertContains( $fullname_field_id, $field_ids );\n\t\t$this->assertContains( $f1, $field_ids );\n\t\t$this->assertContains( $f2, $field_ids );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_the_required_field_name_field() {\n\t\t$g1 = $this->bp::factory()->xprofile_group->create();\n\n\t\t$f1 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'textbox',\n\t\t\t\t'name'           => 'field1',\n\t\t\t]\n\t\t);\n\n\t\t$f2 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'checkbox',\n\t\t\t\t'name'           => 'field2',\n\t\t\t]\n\t\t);\n\n\t\tbp_xprofile_update_field_meta( $f1, 'signup_position', 2 );\n\t\tbp_xprofile_update_field_meta( $f2, 'signup_position', 3 );\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 2',\n\t\t\t]\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\n\t\t$params = $this->set_signup_data(\n\t\t\tarray(\n\t\t\t\t'signup_field_data' => array(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => $f1,\n\t\t\t\t\t\t'value'      => 'Field 1 Value',\n\t\t\t\t\t\t'visibility' => 'public'\n\t\t\t\t\t),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => $f2,\n\t\t\t\t\t\t'value'      => 'Option 1, Option 2',\n\t\t\t\t\t\t'visibility' => 'public'\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_signup_field_required', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_a_custom_required_field_name_field() {\n\t\t$g1 = $this->bp::factory()->xprofile_group->create();\n\n\t\t$f1 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'textbox',\n\t\t\t\t'name'           => 'field1',\n\t\t\t\t'is_required'    => true,\n\t\t\t]\n\t\t);\n\n\t\t$f2 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'checkbox',\n\t\t\t\t'name'           => 'field2',\n\t\t\t]\n\t\t);\n\n\t\tbp_xprofile_update_field_meta( $f1, 'signup_position', 2 );\n\t\tbp_xprofile_update_field_meta( $f2, 'signup_position', 3 );\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 2',\n\t\t\t]\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\n\t\t$params = $this->set_signup_data(\n\t\t\tarray(\n\t\t\t\t'signup_field_data' => array(\n\t\t\t\t\t// Missing the required field.\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => $f2,\n\t\t\t\t\t\t'value'      => 'Option 1, Option 2',\n\t\t\t\t\t\t'visibility' => 'public'\n\t\t\t\t\t),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => bp_xprofile_fullname_field_id(),\n\t\t\t\t\t\t'value'      => 'Test User',\n\t\t\t\t\t\t'visibility' => 'public',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_signup_field_required', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_a_custom_required_field_name_field_value_missing() {\n\t\t$g1 = $this->bp::factory()->xprofile_group->create();\n\n\t\t$f1 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'textbox',\n\t\t\t\t'name'           => 'field1',\n\t\t\t\t'is_required'    => true,\n\t\t\t]\n\t\t);\n\n\t\t$f2 = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'type'           => 'checkbox',\n\t\t\t\t'name'           => 'field2',\n\t\t\t]\n\t\t);\n\n\t\tbp_xprofile_update_field_meta( $f1, 'signup_position', 2 );\n\t\tbp_xprofile_update_field_meta( $f2, 'signup_position', 3 );\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $g1,\n\t\t\t\t'parent_id'      => $f2,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 2',\n\t\t\t]\n\t\t);\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\n\t\t$params = $this->set_signup_data(\n\t\t\tarray(\n\t\t\t\t'signup_field_data' => array(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id' => $f1,\n\t\t\t\t\t\t'value'    => '', // <-- missing value.\n\t\t\t\t\t),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id' => $f2,\n\t\t\t\t\t\t'value'    => 'Option 1, Option 2',\n\t\t\t\t\t),\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id' => bp_xprofile_fullname_field_id(),\n\t\t\t\t\t\t'value'    => 'Test User',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_signup_field_required', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_the_default_required_field_value() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$data    = array(\n\t\t\tarray(\n\t\t\t\t'field_id'   => bp_xprofile_fullname_field_id(),\n\t\t\t\t'value'      => '',\n\t\t\t\t'visibility' => 'public',\n\t\t\t),\n\t\t);\n\n\t\t$params = $this->set_signup_data( array( 'signup_field_data' => $data ) );\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_signup_field_required', $response, 500 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_without_the_signup_field_data_param() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\n\t\t$params = $this->set_signup_data( array( 'signup_field_data' => array() ) );\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_unauthorized_password() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\n\t\t$params = $this->set_signup_data( array( 'password' => '\\\\Antislash' ) );\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_user_invalid_password', $response, 400 );\n\t}\n\n\t/**\n\t * @group activate_item\n\t */\n\tpublic function test_update_item() {\n\t\t$s1 = $this->create_signup();\n\t\t$signup = new BP_Signup( $s1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/activate/%s', $signup->activation_key ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->check_signup_data( $signup, $all_data[0] );\n\t}\n\n\t/**\n\t * @group activate_item\n\t */\n\tpublic function test_update_item_invalid_invalid_activation_key() {\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/activate/%s', 'randomkey' ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_activation_key', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$signup = $this->endpoint->get_signup_object( $this->signup_id );\n\t\t$this->assertEquals( $this->signup_id, $signup->id );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->signup_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$deleted = $response->get_data();\n\n\t\t$this->assertTrue( $deleted['deleted'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_signup_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->signup_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_unauthorized_user() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->signup_id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group resend_item\n\t */\n\tpublic function test_resend_activation_email() {\n\t\t$signup_id = $this->create_signup();\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/resend' );\n\t\t$request->set_param( 'id', $signup_id );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->assertTrue( $all_data['sent'] );\n\t}\n\n\t/**\n\t * @group resend_item\n\t */\n\tpublic function test_resend_acivation_email_to_active_signup() {\n\t\t$signup_id = $this->create_signup();\n\t\t$signup    = new BP_Signup( $signup_id );\n\n\t\tbp_core_activate_signup( $signup->activation_key );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/resend' );\n\t\t$request->set_param( 'id', $signup_id );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\tif ( is_multisite() ) {\n\t\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t\t$all_data = $response->get_data();\n\n\t\t\t$this->assertTrue( $all_data['sent'] );\n\t\t} else {\n\t\t\t$this->assertErrorResponse( 'bp_rest_signup_resend_activation_email_fail', $response, 500 );\n\t\t}\n\t}\n\n\t/**\n\t * @group resend_item\n\t */\n\tpublic function test_resend_activation_email_invalid_signup_id() {\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/resend' );\n\t\t$request->set_param( 'id', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$signup = $this->endpoint->get_signup_object( $this->signup_id );\n\t\t$this->assertEquals( $this->signup_id, $signup->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $this->signup_id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\n\t\t$this->check_signup_data( $signup, $all_data[0] );\n\t}\n\n\tprotected function set_signup_data( $args = array() ) {\n\t\treturn wp_parse_args(\n\t\t\t$args,\n\t\t\tarray(\n\t\t\t\t'user_login'        => 'newnuser',\n\t\t\t\t'user_email'        => 'new.user@example.com',\n\t\t\t\t'password'          => 'password',\n\t\t\t\t'signup_field_data' => array(\n\t\t\t\t\tarray(\n\t\t\t\t\t\t'field_id'   => bp_xprofile_fullname_field_id(),\n\t\t\t\t\t\t'value'      => 'New User',\n\t\t\t\t\t\t'visibility' => 'public',\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\t}\n\n\tprotected function create_signup() {\n\t\treturn BP_Signup::add(\n\t\t\tarray(\n\t\t\t\t'user_login'     => 'user' . wp_rand( 1, 20 ),\n\t\t\t\t'user_email'     => sprintf( 'user%d@example.com', wp_rand( 1, 20 ) ),\n\t\t\t\t'registered'     => bp_core_current_time(),\n\t\t\t\t'activation_key' => wp_generate_password( 32, false ),\n\t\t\t\t'meta'           => array(\n\t\t\t\t\t'field_1' => 'Foo Bar',\n\t\t\t\t),\n\t\t\t)\n\t\t);\n\t}\n\n\tprotected function check_signup_data( $signup, $data ) {\n\t\t$this->assertEquals( $signup->id, $data['id'] );\n\t\t$this->assertEquals( $signup->user_login, $data['user_login'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $signup->registered, get_date_from_gmt( $signup->registered ) ),\n\t\t\t$data['registered']\n\t\t);\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $signup->registered ), $data['registered_gmt'] );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->signup_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\tif ( is_multisite() ) {\n\t\t\t$this->assertEquals( 15, count( $properties ) );\n\t\t} else {\n\t\t\t$this->assertEquals( 11, count( $properties ) );\n\t\t}\n\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'user_login', $properties );\n\t\t$this->assertArrayHasKey( 'registered', $properties );\n\t\t$this->assertArrayHasKey( 'registered_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'activation_key', $properties );\n\t\t$this->assertArrayHasKey( 'user_email', $properties );\n\t\t$this->assertArrayHasKey( 'date_sent', $properties );\n\t\t$this->assertArrayHasKey( 'date_sent_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'count_sent', $properties );\n\t\t$this->assertArrayHasKey( 'meta', $properties );\n\n\t\tif ( is_multisite() ) {\n\t\t\t$this->assertArrayHasKey( 'site_language', $properties );\n\t\t\t$this->assertArrayHasKey( 'site_public', $properties );\n\t\t\t$this->assertArrayHasKey( 'site_title', $properties );\n\t\t\t$this->assertArrayHasKey( 'site_name', $properties );\n\t\t}\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\n\t\t// Single.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->signup_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/sitewide-notices/test-controller.php",
    "content": "<?php\n/**\n * Sitewide Notices Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group notices\n */\nclass BP_Test_REST_Sitewide_Notices_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $server;\n\tprotected $last_inserted_notice_id;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_Sitewide_Notices_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/sitewide-notices';\n\t\t$this->user         = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\n\t\tadd_action( 'messages_notice_before_save', array( $this, 'add_filter_update_last_active_query' ), 10, 0 );\n\t\tadd_action( 'messages_notice_after_save', array( $this, 'set_last_inserted_notice_id' ), 10, 1 );\n\t}\n\n\tpublic function tear_down() {\n\t\tremove_action( 'messages_notice_before_save', array( $this, 'filter_update_last_active_query' ), 10 );\n\t\tremove_action( 'messages_notice_after_save', array( $this, 'set_last_inserted_notice_id' ), 10 );\n\n\t\tparent::tear_down();\n\t}\n\n\tpublic function catch_inserted_id( $query ) {\n\t\tpreg_match( '/SET is_active = 0 WHERE id != (.*)/', $query, $matches );\n\t\tif ( isset( $matches[1] ) && $matches[1] ) {\n\t\t\t$this->last_inserted_notice_id = (int) $matches[1];\n\t\t}\n\n\t\treturn $query;\n\t}\n\n\tpublic function add_filter_update_last_active_query() {\n\t\tadd_filter( 'query', array( $this, 'catch_inserted_id' ) );\n\t}\n\n\tpublic function set_last_inserted_notice_id( $notice_obj ) {\n\t\tremove_filter( 'query', array( $this, 'catch_inserted_id' ) );\n\n\t\tif ( $this->last_inserted_notice_id ) {\n\t\t\t$notice_obj->id = $this->last_inserted_notice_id;\n\t\t\t$this->last_inserted_notice_id = null;\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes   = $this->server->get_routes();\n\t\t$endpoint = $this->endpoint_url;\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 2, $routes[ $endpoint ] );\n\n\t\t// Single.\n\t\t$single_endpoint = $endpoint . '/(?P<id>[\\d]+)';\n\n\t\t$this->assertArrayHasKey( $single_endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $single_endpoint ] );\n\n\t\t// Dismiss.\n\t\t$dismiss_endpoint = $endpoint . '/dismiss';\n\n\t\t$this->assertArrayHasKey( $dismiss_endpoint, $routes );\n\t\t$this->assertCount( 1, $routes[ $dismiss_endpoint ] );\n\t}\n\n\tpublic function create_notice( $notices = array() ) {\n\t\t$created = array();\n\n\t\tforeach ( $notices as $notice ) {\n\t\t\t$props = wp_parse_args(\n\t\t\t\t$notice,\n\t\t\t\tarray(\n\t\t\t\t\t'subject'   => 'example subject',\n\t\t\t\t\t'message'   => 'example message',\n\t\t\t\t\t'date_sent' => bp_core_current_time(),\n\t\t\t\t\t'is_active' => 1,\n\t\t\t\t)\n\t\t\t);\n\n\t\t\t$new_notice = new BP_Messages_Notice();\n\n\t\t\tforeach ( $props as $key => $prop ) {\n\t\t\t\t$new_notice->{$key} = $prop;\n\t\t\t}\n\n\t\t\tif ( $new_notice->save() ) {\n\t\t\t\t$created[] = $new_notice;\n\t\t\t}\n\t\t}\n\n\t\treturn $created;\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'foo',\n\t\t\t),\n\t\t\t'n2' => array(\n\t\t\t\t'subject' => 'bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\t\t$this->assertTrue( 2 === count( $all_data ) );\n\n\t\t$data   = wp_list_filter( $all_data, array( 'is_active' => true ) );\n\t\t$data_n = reset( $data );\n\n\t\t$n = wp_filter_object_list( $created, array( 'id' => $data_n['id'] ), 'and', 'id' );\n\t\t$key = key( $n );\n\n\t\t$this->check_notice_data( $created[ $key ], $data_n, 'edit' );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_no_edit_access() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'foo',\n\t\t\t),\n\t\t\t'n2' => array(\n\t\t\t\t'subject' => 'bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_forbidden', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_view_active() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject'   => 'foo',\n\t\t\t\t'is_active' => 0,\n\t\t\t),\n\t\t\t'n2' => array(\n\t\t\t\t'subject' => 'bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$n   = wp_filter_object_list( $created, array( 'is_active' => 1 ), 'and', 'id' );\n\t\t$key = key( $n );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertTrue( 1 === count( $data ), 'There should only be one active notice in the view context' );\n\n\t\t$active_notice = current( $data );\n\t\t$this->check_notice_data( $created[ $key ], $active_notice, 'view' );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_no_active() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertTrue( 0 === count( $data ), 'There should be no active notices available' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject'   => 'foo',\n\t\t\t\t'is_active' => 0,\n\t\t\t),\n\t\t\t'n2' => array(\n\t\t\t\t'subject' => 'bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\n\t\t$n   = wp_filter_object_list( $created, array( 'is_active' => 1 ), 'and', 'id' );\n\t\t$id  = current( $n );\n\t\t$key = key( $n );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->check_notice_data( $created[ $key ], $data, 'view' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_admin_access() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject'   => 'foo',\n\t\t\t\t'is_active' => 0,\n\t\t\t),\n\t\t\t'n2' => array(\n\t\t\t\t'subject' => 'bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\n\t\t$n   = wp_filter_object_list( $created, array( 'is_active' => 0 ), 'and', 'id' );\n\t\t$id  = current( $n );\n\t\t$key = key( $n );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->check_notice_data( $created[ $key ], $data, 'edit' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_no_access() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject'   => 'foo',\n\t\t\t\t'is_active' => 0,\n\t\t\t),\n\t\t\t'n2' => array(\n\t\t\t\t'subject' => 'bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\n\t\t$n   = wp_filter_object_list( $created, array( 'is_active' => 0 ), 'and', 'id' );\n\t\t$id  = current( $n );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_view_active() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject'   => 'bar',\n\t\t\t\t'is_active' => 0,\n\t\t\t),\n\t\t\t'n2' => array(\n\t\t\t\t'subject' => 'foo',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\n\t\t$n   = wp_filter_object_list( $created, array( 'is_active' => 1 ), 'and', 'id' );\n\t\t$id  = current( $n );\n\t\t$key = key( $n );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->check_notice_data( $created[ $key ], $data, 'view' );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'subject' => 'Foo Bar',\n\t\t\t\t'message' => 'Content',\n\t\t\t)\n\t\t);\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertTrue( $data['is_active'] );\n\t\t$this->assertSame( 'Content', $data['message']['raw'] );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_no_access() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'subject' => 'Foo Bar',\n\t\t\t\t'message' => 'Ouch!',\n\t\t\t)\n\t\t);\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_no_subject() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->set_query_params(\n\t\t\tarray(\n\t\t\t\t'subject' => '',\n\t\t\t\t'message' => 'Aïe!',\n\t\t\t)\n\t\t);\n\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_user_cannot_create_sitewide_notice', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject'   => 'Foo Bar',\n\t\t\t\t'is_active' => 0,\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$n = current( $created );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $n->id ) );\n\t\t$request->set_param( 'is_active', true );\n\t\t$request->set_param( 'message', 'Yeah!' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertTrue( $data['is_active'] );\n\t\t$this->assertSame( 'Yeah!', $data['message']['raw'] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_no_access() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'Foo Bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$n = current( $created );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $n->id ) );\n\t\t$request->set_param( 'message', 'Ouch!' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_no_message() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'Foo Bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$n = current( $created );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $n->id ) );\n\t\t$request->set_param( 'message', '' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_sitewide_notices_update_failed', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_with_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->set_param( 'message', 'Ouch!' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'Foo Bar',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$n = current( $created );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $n->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertTrue( $data['deleted'] );\n\t\t$this->assertTrue( $data['previous']['subject']['raw'] === 'Foo Bar' );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_no_access() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'Ouch!',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$n = current( $created );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $n->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_with_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group dismiss_item\n\t */\n\tpublic function test_dismiss_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'Taz',\n\t\t\t),\n\t\t);\n\n\t\t$created = $this->create_notice( $tested );\n\t\t$n = current( $created );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/dismiss' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertTrue( $data['dismissed'] );\n\t\t$this->assertTrue( $data['previous']['subject']['rendered'] === 'Taz' );\n\t\t$this->assertContains( $n->id, bp_get_user_meta( $u1, 'closed_notices', true ) );\n\t}\n\n\t/**\n\t * @group dismiss_item\n\t */\n\tpublic function test_dismiss_item_no_actives() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject'   => 'Taz',\n\t\t\t\t'is_active' => 0,\n\t\t\t),\n\t\t);\n\n\t\t$this->create_notice( $tested );\n\n\t\t$u1 = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/dismiss' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group dismiss_item\n\t */\n\tpublic function test_dismiss_item_not_logged_in() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$tested = array(\n\t\t\t'n1' => array(\n\t\t\t\t'subject' => 'Taz',\n\t\t\t),\n\t\t);\n\n\t\t$this->create_notice( $tested );\n\n\t\t$this->bp::set_current_user( 0 );\n\n\t\t$request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/dismiss' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\tprotected function check_notice_data( $notice, $data, $context = 'view' ) {\n\t\t$this->assertEquals( $notice->id, $data['id'] );\n\n\t\tif ( 'edit' === $context ) {\n\t\t\t$this->assertEquals( $notice->subject, $data['subject']['raw'] );\n\t\t\t$this->assertEquals( $notice->message, $data['message']['raw'] );\n\t\t\t$this->assertEquals( (bool) $notice->is_active, $data['is_active'] );\n\t\t}\n\n\t\t$this->assertEquals( apply_filters( 'bp_get_message_notice_subject', wp_staticize_emoji( $notice->subject ) ), $data['subject']['rendered'] );\n\t\t$this->assertEquals( apply_filters( 'bp_get_message_notice_text', wp_staticize_emoji( $notice->message ) ), $data['message']['rendered'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $notice->date_sent, get_date_from_gmt( $notice->date_sent ) ),\n\t\t\t$data['date']\n\t\t);\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $notice->date_sent ), $data['date_gmt'] );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 6, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'subject', $properties );\n\t\t$this->assertArrayHasKey( 'message', $properties );\n\t\t$this->assertArrayHasKey( 'date', $properties );\n\t\t$this->assertArrayHasKey( 'date_gmt', $properties );\n\t\t$this->assertArrayHasKey( 'is_active', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/xprofile/test-data-controller.php",
    "content": "<?php\n/**\n * XProfile Data Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group xprofile-data\n */\nclass BP_Test_REST_XProfile_Data_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $server;\n\tprotected $group_id;\n\tprotected $field;\n\tprotected $field_id;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_XProfile_Data_Endpoint();\n\t\t$this->field        = new BP_REST_XProfile_Fields_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->profile->id . '/';\n\t\t$this->group_id     = $this->bp::factory()->xprofile_group->create();\n\t\t$this->field_id     = $this->bp::factory()->xprofile_field->create( [ 'field_group_id' => $this->group_id ] );\n\n\t\t$this->user = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t$endpoint = $this->endpoint_url . '(?P<field_id>[\\d]+)/data/(?P<user_id>[\\d]+)';\n\n\t\t$this->assertArrayHasKey( $endpoint, $routes );\n\t\t$this->assertCount( 3, $routes[ $endpoint ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\txprofile_set_field_data( $this->field_id, $this->user, 'foo' );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertEquals( $all_data[0]['value']['unserialized'], array( 'foo' ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\txprofile_set_field_data( $this->field_id, $this->user, 'foo' );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_hidden_for_user() {\n\t\t$f = $this->bp::factory()->xprofile_field->create( array( 'field_group_id' => $this->group_id ) );\n\t\txprofile_set_field_data( $f, $this->user, 'bar' );\n\t\txprofile_set_field_visibility_level( $f, $this->user, 'adminsonly' );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/data/%d', $f, $this->user ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertEquals( 403, $response->get_status() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_field_response( $response );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_checkbox() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'checkbox',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Field',\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Value',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( $data[0]['value']['unserialized'], [ 'Field', 'Value' ] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_multiselectbox() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'multiselectbox',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 2',\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 3',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => 'Option 1,Option 2' ] );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( $data[0]['value']['unserialized'], [ 'Option 1', 'Option 2' ] );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_multiselectbox_with_invalid_item() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'multiselectbox',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => 'option 1' ] );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_user_cannot_save_xprofile_data', $response, 500 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_multiselectbox_with_empty_value() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'multiselectbox',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\txprofile_set_field_data( $field_id, $this->user, 'Option 1' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t// Clear selected options.\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => '' ] );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( $data[0]['value']['unserialized'], [] );\n\t}\n\n\t/**\n\t * @group update_item\n\t *\n\t * @ticket https://buddypress.trac.wordpress.org/ticket/9127\n\t */\n\tpublic function test_update_multiselectbox_with_apostrophe_value() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'multiselectbox',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\txprofile_insert_field(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => \"I don't travel often\",\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => \"I don\\'t travel often\" ] );\n\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( $data[0]['value']['unserialized'], [ \"I don\\'t travel often\" ] );\n\t\t$this->assertEquals( $data[0]['value']['raw'], \"a:1:{i:0;s:21:\\\"I don\\\\'t travel often\\\";}\" );\n\t}\n\n\t/**\n\t * @group update_item\n\t *\n\t * @ticket https://buddypress.trac.wordpress.org/ticket/9127\n\t */\n\tpublic function test_update_checkbox_with_apostrophe_value() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'checkbox',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'Option 1',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => \"I don't travel often\",\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => \"I don\\'t travel often\" ] );\n\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( $data[0]['value']['unserialized'], [ \"I don\\'t travel often\" ] );\n\t\t$this->assertEquals( $data[0]['value']['raw'], \"a:1:{i:0;s:21:\\\"I don\\\\'t travel often\\\";}\" );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_textbox() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'textbox',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => 'textbox field' ] );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( $data[0]['value']['unserialized'][0], $params['value'] );\n\t\t$this->assertEquals( $data[0]['value']['raw'], 'textbox field' );\n\t}\n\n\t/**\n\t * @group update_item\n\t *\n\t * @ticket https://buddypress.trac.wordpress.org/ticket/9127\n\t */\n\tpublic function test_update_textbox_with_apostrophe_value() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'textbox',\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'value'          => 'textbox field',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => \"I don't travel often\" ] );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertEquals( $data[0]['value']['raw'], \"I don't travel often\" );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => \"I don\\\\'t travel often\" ] );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$data = $response->get_data();\n\n\t\t$this->assertNotEmpty( $data );\n\t\t$this->assertEquals( $data[0]['value']['raw'], \"I don't travel often\" );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_selectbox() {\n\t\t$field_id = $this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'type'           => 'selectbox',\n\t\t\t\t'name'           => 'Test Field Name',\n\t\t\t\t'field_group_id' => $this->group_id\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::factory()->xprofile_field->create(\n\t\t\t[\n\t\t\t\t'field_group_id' => $this->group_id,\n\t\t\t\t'parent_id'      => $field_id,\n\t\t\t\t'type'           => 'option',\n\t\t\t\t'name'           => 'select box',\n\t\t\t]\n\t\t);\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'value' => 'select box' ] );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertEquals( $data[0]['value']['unserialized'][0], 'select box' );\n\t\t$this->assertEquals( $data[0]['value']['raw'], 'select box' );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$request->set_body( wp_json_encode( $this->set_field_data() ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_without_permission() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$request->set_body( wp_json_encode( $this->set_field_data() ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_without_permission_with_param() {\n\t\t$u1 = static::factory()->user->create();\n\t\t$u2 = static::factory()->user->create();\n\n\t\t$this->bp::set_current_user( $u1 );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $u2 ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$request->set_body( wp_json_encode( $this->set_field_data() ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_field_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_member_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->markTestSkipped();\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$g = $this->bp::factory()->xprofile_group->create();\n\t\t$f = $this->bp::factory()->xprofile_field->create( [ 'field_group_id' => $g ] );\n\n\t\txprofile_set_field_data( $f, $this->user, 'foo' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/data/%d', $f, $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertTrue( 'foo' === $data['previous']['value']['raw'] );\n\n\t\t$field_data = $this->endpoint->get_xprofile_field_data_object( $data['previous']['field_id'], $data['previous']['user_id'] );\n\n\t\t$this->assertEmpty( $field_data->value );\n\t\t$this->assertEmpty( $field_data->last_updated );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_field_owner_can_delete() {\n\t\t$u = $this->bp::factory()->user->create();\n\t\t$g = $this->bp::factory()->xprofile_group->create();\n\t\t$f = $this->bp::factory()->xprofile_field->create( array(\n\t\t\t'field_group_id' => $g,\n\t\t) );\n\n\t\txprofile_set_field_data( $f, $u, 'bar' );\n\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/data/%d', $f, $u ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->assertTrue( 'bar' === $data['previous']['value']['raw'] );\n\n\t\t$field_data = $this->endpoint->get_xprofile_field_data_object( $data['previous']['field_id'], $data['previous']['user_id'] );\n\n\t\t$this->assertEmpty( $field_data->value );\n\t\t$this->assertEmpty( $field_data->last_updated );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_field_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/data/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER, $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_user_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_without_permission() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\t\txprofile_set_field_data( $this->field_id, $this->user, 'foo' );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->assertEquals( $all_data[0]['value']['unserialized'], array( 'foo' ) );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields() {\n\t\tbp_rest_register_field( 'xprofile', 'foo_metadata_key', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'xProfile data Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t), 'data' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'bar_metadata_value';\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( array(\n\t\t\t'foo_metadata_key' => $expected,\n\t\t) );\n\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$this->assertNotEmpty( $create_data );\n\t\t$this->assertTrue( $expected === $create_data[0]['foo_metadata_key'] );\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn bp_xprofile_update_meta( $data->id, 'data', '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_xprofile_get_meta( $data['id'], 'data', '_' . $attribute );\n\t}\n\n\tprotected function check_create_field_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$field_data = $this->endpoint->get_xprofile_field_data_object( $data[0]['field_id'], $data[0]['user_id'] );\n\t\t$this->check_field_data( $field_data, $data[0] );\n\t}\n\n\tprotected function set_field_data( $args = array() ) {\n\t\treturn wp_parse_args(\n\t\t\t$args,\n\t\t\t[\n\t\t\t\t'value' => 'Field,Value',\n\t\t\t]\n\t\t);\n\t}\n\n\tprotected function check_field_data( $field_data, $data ) {\n\t\t$this->assertEquals( $field_data->field_id, $data['field_id'] );\n\t\t$this->assertEquals( $field_data->user_id, $data['user_id'] );\n\t\t$this->assertEquals( (array) $field_data->value, $data['value']['unserialized'] );\n\t\t$this->assertEquals(\n\t\t\tbp_rest_prepare_date_response( $field_data->last_updated, get_date_from_gmt( $field_data->last_updated ) ),\n\t\t\t$data['last_updated']\n\t\t);\n\t\t$this->assertEquals( bp_rest_prepare_date_response( $field_data->last_updated ), $data['last_updated_gmt'] );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '%d/data/%d', $this->field_id, $this->user ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 7, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'field_id', $properties );\n\t\t$this->assertArrayHasKey( 'user_id', $properties );\n\t\t$this->assertArrayHasKey( 'value', $properties );\n\t\t$this->assertArrayHasKey( 'last_updated', $properties );\n\t\t$this->assertArrayHasKey( 'last_updated_gmt', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t$this->markTestSkipped();\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/xprofile/test-field-controller.php",
    "content": "<?php\n/**\n * XProfile Field Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group xprofile-field\n */\nclass BP_Test_REST_XProfile_Fields_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $server;\n\tprotected $group_id;\n\tprotected $field_id;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_XProfile_Fields_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->profile->id . '/fields';\n\t\t$this->group_id     = $this->bp::factory()->xprofile_group->create();\n\t\t$this->field_id     = $this->bp::factory()->xprofile_field->create( [ 'field_group_id' => $this->group_id ] );\n\n\t\t$this->user = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\d]+)', $routes );\n\t\t$this->assertCount( 3, $routes[ $this->endpoint_url . '/(?P<id>[\\d]+)' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$this->bp::factory()->xprofile_field->create_many( 5, [ 'field_group_id' => $this->group_id ] );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\tforeach ( $all_data as $data ) {\n\t\t\t$field = $this->endpoint->get_xprofile_field_object( $data['id'] );\n\t\t\t$this->check_field_data( $field, $data );\n\t\t}\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_public_get_items() {\n\t\t$this->bp::factory()->xprofile_field->create_many( 5, [ 'field_group_id' => $this->group_id ] );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->check_field_data(\n\t\t\t$this->endpoint->get_xprofile_field_object( $data[0]['id'] ),\n\t\t\t$data[0]\n\t\t);\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_public_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$this->bp::factory()->xprofile_field->create_many( 5, [ 'field_group_id' => $this->group_id ] );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_include_groups() {\n\t\t$g1 = $this->bp::factory()->xprofile_group->create();\n\t\t$g2 = $this->bp::factory()->xprofile_group->create();\n\t\t$this->bp::factory()->xprofile_field->create_many( 3, [ 'field_group_id' => $g1 ] );\n\t\t$this->bp::factory()->xprofile_field->create_many( 2, [ 'field_group_id' => $g2 ] );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'include_groups', array( $g2 ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$this->check_field_data(\n\t\t\t$this->endpoint->get_xprofile_field_object( $data[0]['id'] ),\n\t\t\t$data[0]\n\t\t);\n\n\t\t$this->assertEmpty( wp_filter_object_list( $data, array( 'group_id' => $g1 ) ) );\n\t\t$this->assertTrue( 2 === count( wp_filter_object_list( $data, array( 'group_id' => $g2 ) ) ) );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$field = $this->endpoint->get_xprofile_field_object( $this->field_id );\n\t\t$this->assertEquals( $this->field_id, $field->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $field->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_field_data( $field, $all_data[0] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_public_item() {\n\t\t$field = $this->endpoint->get_xprofile_field_object( $this->field_id );\n\t\t$this->assertEquals( $this->field_id, $field->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $field->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_field_data( $field, $all_data[0] );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_public_item_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$field = $this->endpoint->get_xprofile_field_object( $this->field_id );\n\t\t$this->assertEquals( $this->field_id, $field->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $field->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_with_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_field_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_rest_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_field_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_without_required_field() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( array( 'type' => '' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_with_invalid_type() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( array( 'type' => 'group' ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_without_permission() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$new_name = 'Updated name';\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->field_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'name' => $new_name, 'group_id' => $this->group_id ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$object  = end( $all_data );\n\t\t$updated = $this->endpoint->get_xprofile_field_object( $object['id'] );\n\n\t\t$this->assertSame( $new_name, $updated->name );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$params  = $this->set_field_data( [ 'group_id' => $this->group_id ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->field_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_data( [ 'group_id' => $this->group_id ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_permission() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->field_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$params  = $this->set_field_data( [ 'group_id' => $this->group_id ] );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$field = $this->endpoint->get_xprofile_field_object( $this->field_id );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $field->id ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_field_data( $field, $all_data['previous'] );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->field_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_without_permission() {\n\t\t$u = static::factory()->user->create( array( 'role' => 'subscriber' ) );\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->field_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$field = $this->endpoint->get_xprofile_field_object( $this->field_id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $field->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_field_data( $field, $all_data[0] );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'xprofile', 'foo_field_key', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'xProfile Field Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t), 'field' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'bar_field_value';\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$params = $this->set_field_data( array( 'foo_field_key' => $expected ) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $create_data[0]['foo_field_key'] );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $create_data[0]['id'] ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $get_data[0]['foo_field_key'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_update_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'xprofile', 'bar_field_key', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'xProfile Group Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t), 'field' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'foo_field_value';\n\n\t\t// PUT\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->field_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$params = $this->set_field_data( array(\n\t\t\t'name'          => $this->endpoint->get_xprofile_field_object( $this->field_id )->name,\n\t\t\t'group_id'      => $this->group_id,\n\t\t\t'bar_field_key' => $expected,\n\t\t) );\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$update_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $update_data[0]['bar_field_key'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn bp_xprofile_update_meta( $data->id, 'field', '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_xprofile_get_meta( $data['id'], 'field', '_' . $attribute );\n\t}\n\n\tprotected function check_create_field_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$field = $this->endpoint->get_xprofile_field_object( $data[0]['id'] );\n\t\t$this->check_field_data( $field, $data[0], 'edit' );\n\t}\n\n\tprotected function set_field_data( $args = array() ) {\n\t\treturn wp_parse_args( $args, array(\n\t\t\t'type'     => 'checkbox',\n\t\t\t'name'     => 'Test Field Name',\n\t\t\t'group_id' => $this->group_id,\n\t\t) );\n\t}\n\n\tprotected function check_field_data( $field, $data, $context = 'view' ) {\n\t\t$this->assertEquals( $field->id, $data['id'] );\n\t\t$this->assertEquals( $field->group_id, $data['group_id'] );\n\t\t$this->assertEquals( $field->parent_id, $data['parent_id'] );\n\t\t$this->assertEquals( $field->type, $data['type'] );\n\t\t$this->assertEquals( $field->name, $data['name'] );\n\n\t\tif ( 'view' === $context ) {\n\t\t\t$this->assertEquals( $field->description, $data['description']['rendered'] );\n\t\t} else {\n\t\t\t$this->assertEquals( $field->description, $data['description']['raw'] );\n\t\t}\n\n\t\t$this->assertEquals( $field->is_required, $data['is_required'] );\n\t\t$this->assertEquals( $field->can_delete, $data['can_delete'] );\n\t\t$this->assertEquals( $field->field_order, $data['field_order'] );\n\t\t$this->assertEquals( $field->option_order, $data['option_order'] );\n\t\t$this->assertEquals( strtoupper( $field->order_by ), $data['order_by'] );\n\t\t$this->assertEquals( $field->is_default_option, $data['is_default_option'] );\n\n\t\tif ( ! empty( $data['visibility_level'] ) ) {\n\t\t\t$this->assertEquals( $field->visibility_level, $data['visibility_level'] );\n\t\t}\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->field_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 15, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'group_id', $properties );\n\t\t$this->assertArrayHasKey( 'parent_id', $properties );\n\t\t$this->assertArrayHasKey( 'type', $properties );\n\t\t$this->assertArrayHasKey( 'name', $properties );\n\t\t$this->assertArrayHasKey( 'description', $properties );\n\t\t$this->assertArrayHasKey( 'is_required', $properties );\n\t\t$this->assertArrayHasKey( 'can_delete', $properties );\n\t\t$this->assertArrayHasKey( 'field_order', $properties );\n\t\t$this->assertArrayHasKey( 'option_order', $properties );\n\t\t$this->assertArrayHasKey( 'order_by', $properties );\n\t\t$this->assertArrayHasKey( 'options', $properties );\n\t\t$this->assertArrayHasKey( 'is_default_option', $properties );\n\t\t$this->assertArrayHasKey( 'visibility_level', $properties );\n\t\t$this->assertArrayHasKey( 'data', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n}\n"
  },
  {
    "path": "tests/testcases/xprofile/test-group-controller.php",
    "content": "<?php\n/**\n * XProfile Field Groups Endpoint Tests.\n *\n * @package BuddyPress\n * @subpackage BP_REST\n * @group xprofile-group\n */\nclass BP_Test_REST_XProfile_Groups_Endpoint extends WP_Test_REST_Controller_Testcase {\n\tprotected $endpoint;\n\tprotected $bp;\n\tprotected $endpoint_url;\n\tprotected $user;\n\tprotected $server;\n\tprotected $group_id;\n\n\tpublic function set_up() {\n\t\tparent::set_up();\n\n\t\t$this->endpoint     = new BP_REST_XProfile_Field_Groups_Endpoint();\n\t\t$this->bp           = new BP_UnitTestCase();\n\t\t$this->endpoint_url = '/' . bp_rest_namespace() . '/' . bp_rest_version() . '/' . buddypress()->profile->id . '/groups';\n\t\t$this->group_id     = $this->bp::factory()->xprofile_group->create();\n\n\t\t$this->user = static::factory()->user->create( array(\n\t\t\t'role'       => 'administrator',\n\t\t\t'user_email' => 'admin@example.com',\n\t\t) );\n\n\t\tif ( ! $this->server ) {\n\t\t\t$this->server = rest_get_server();\n\t\t}\n\t}\n\n\tpublic function test_register_routes() {\n\t\t$routes = $this->server->get_routes();\n\n\t\t// Main.\n\t\t$this->assertArrayHasKey( $this->endpoint_url, $routes );\n\t\t$this->assertCount( 2, $routes[ $this->endpoint_url ] );\n\n\t\t// Single.\n\t\t$this->assertArrayHasKey( $this->endpoint_url . '/(?P<id>[\\d]+)', $routes );\n\t\t$this->assertCount( 3, $routes[ $this->endpoint_url . '/(?P<id>[\\d]+)' ] );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$this->bp::factory()->xprofile_group->create_many( 5 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\tforeach ( $all_data as $data ) {\n\t\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $data['id'] );\n\t\t\t$this->check_group_data( $field_group, $data, 'view', $response->get_links() );\n\t\t}\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$this->bp::factory()->xprofile_group->create_many( 5 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_include_groups() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$g1 = $this->bp::factory()->xprofile_group->create();\n\t\t$g2 = $this->bp::factory()->xprofile_group->create();\n\t\t$this->bp::factory()->xprofile_group->create_many( 3 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$request->set_param( 'include_groups', array( $g1, $g2 ) );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\tforeach ( $all_data as $data ) {\n\t\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $data['id'] );\n\t\t\t$this->check_group_data( $field_group, $data, 'view', $response->get_links() );\n\t\t}\n\n\t\t$group_ids = wp_list_pluck( $all_data, 'id' );\n\t\tsort( $group_ids );\n\t\t$this->assertSame( $group_ids, array( $g1, $g2 ) );\n\t}\n\n\t/**\n\t * @group get_items\n\t */\n\tpublic function test_get_items_publicly() {\n\t\t$this->bp::factory()->xprofile_group->create_many( 5 );\n\n\t\t$request = new WP_REST_Request( 'GET', $this->endpoint_url );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\tforeach ( $all_data as $data ) {\n\t\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $data['id'] );\n\t\t\t$this->check_group_data( $field_group, $data, 'view', $response->get_links() );\n\t\t}\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $this->group_id );\n\t\t$this->assertEquals( $this->group_id, $field_group->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $field_group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_group_data( $field_group, $all_data[0], 'view', $response->get_links() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_publicly_with_support_for_the_community_visibility() {\n\t\ttoggle_component_visibility();\n\n\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $this->group_id );\n\t\t$this->assertEquals( $this->group_id, $field_group->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $field_group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_publicly() {\n\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $this->group_id );\n\t\t$this->assertEquals( $this->group_id, $field_group->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $field_group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_group_data( $field_group, $all_data[0], 'view', $response->get_links() );\n\t}\n\n\t/**\n\t * @group get_item\n\t */\n\tpublic function test_get_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\n\t\t$params = $this->set_field_group_data();\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_field_group_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_rest_create_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_group_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->check_create_field_group_response( $response );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_not_logged_in() {\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_group_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group create_item\n\t */\n\tpublic function test_create_item_user_without_permission() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\n\t\t$params = $this->set_field_group_data();\n\t\t$request->set_body( wp_json_encode( $params ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item() {\n\t\t$new_name = 'Updated name';\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$request->set_body( wp_json_encode( [ 'name' => $new_name ] ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$object  = end( $all_data );\n\t\t$updated = $this->endpoint->get_xprofile_field_group_object( $object['id'] );\n\n\t\t$this->assertSame( $new_name, $updated->name );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group update_item\n\t */\n\tpublic function test_update_item_without_permission() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request  = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $this->group_id );\n\n\t\t$request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $field_group->id ) );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_group_data( $field_group, $all_data['previous'], 'view', $response->get_links() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_invalid_id() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_user_not_logged_in() {\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group delete_item\n\t */\n\tpublic function test_delete_item_without_permission() {\n\t\t$u = static::factory()->user->create();\n\t\t$this->bp::set_current_user( $u );\n\n\t\t$request  = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );\n\t}\n\n\t/**\n\t * @group prepare_item\n\t */\n\tpublic function test_prepare_item() {\n\t\t$this->bp::set_current_user( $this->user );\n\n\t\t$group = $this->endpoint->get_xprofile_field_group_object( $this->group_id );\n\t\t$this->assertEquals( $this->group_id, $group->id );\n\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $group->id ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$all_data = $response->get_data();\n\t\t$this->assertNotEmpty( $all_data );\n\n\t\t$this->check_group_data( $group, $all_data[0], 'view', $response->get_links() );\n\t}\n\n\tprotected function check_create_field_group_response( $response ) {\n\t\t$this->assertNotInstanceOf( 'WP_Error', $response );\n\t\t$response = rest_ensure_response( $response );\n\n\t\t$this->assertEquals( 200, $response->get_status() );\n\n\t\t$data = $response->get_data();\n\t\t$this->assertNotEmpty( $data );\n\n\t\t$field_group = $this->endpoint->get_xprofile_field_group_object( $data[0]['id'] );\n\t\t$this->check_group_data( $field_group, $data[0], 'view', $response->get_links() );\n\t}\n\n\tprotected function check_group_data( $group, $data, $context, $links ) {\n\t\t$this->assertEquals( $group->id, $data['id'] );\n\t\t$this->assertEquals( $group->name, $data['name'] );\n\t\t$this->assertEquals( $group->group_order, $data['group_order'] );\n\t\t$this->assertEquals( $group->can_delete, $data['can_delete'] );\n\n\t\tif ( 'view' === $context ) {\n\t\t\t$this->assertEquals( $group->description, $data['description']['rendered'] );\n\t\t} else {\n\t\t\t$this->assertEquals( $group->description, $data['description']['raw'] );\n\t\t}\n\t}\n\n\tprotected function set_field_group_data( $args = array() ) {\n\t\treturn wp_parse_args( $args, array(\n\t\t\t'description' => 'Field Group Description',\n\t\t\t'name'        => 'Test Field Name',\n\t\t\t'can_delete'  => true,\n\t\t) );\n\t}\n\n\tpublic function test_get_item_schema() {\n\t\t$request    = new WP_REST_Request( 'OPTIONS', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$response   = $this->server->dispatch( $request );\n\t\t$data       = $response->get_data();\n\t\t$properties = $data['schema']['properties'];\n\n\t\t$this->assertEquals( 6, count( $properties ) );\n\t\t$this->assertArrayHasKey( 'id', $properties );\n\t\t$this->assertArrayHasKey( 'name', $properties );\n\t\t$this->assertArrayHasKey( 'description', $properties );\n\t\t$this->assertArrayHasKey( 'group_order', $properties );\n\t\t$this->assertArrayHasKey( 'can_delete', $properties );\n\t\t$this->assertArrayHasKey( 'fields', $properties );\n\t}\n\n\tpublic function test_context_param() {\n\t\t// Collection.\n\t\t$request  = new WP_REST_Request( 'OPTIONS', $this->endpoint_url );\n\t\t$response = $this->server->dispatch( $request );\n\t\t$data     = $response->get_data();\n\n\t\t$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );\n\t\t$this->assertEquals( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );\n\t}\n\n\tpublic function update_additional_field( $value, $data, $attribute ) {\n\t\treturn bp_xprofile_update_meta( $data->id, 'group', '_' . $attribute, $value );\n\t}\n\n\tpublic function get_additional_field( $data, $attribute )  {\n\t\treturn bp_xprofile_get_meta( $data['id'], 'group', '_' . $attribute );\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'xprofile', 'foo_group_key', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'xProfile Group Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t), 'group' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'bar_group_value';\n\n\t\t// POST\n\t\t$request = new WP_REST_Request( 'POST', $this->endpoint_url );\n\t\t$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );\n\t\t$params = $this->set_field_group_data( array( 'foo_group_key' => $expected ) );\n\t\t$request->set_body_params( $params );\n\t\t$request->set_param( 'context', 'edit' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$create_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $create_data[0]['foo_group_key'] );\n\n\t\t// GET\n\t\t$request = new WP_REST_Request( 'GET', sprintf( $this->endpoint_url . '/%d', $create_data[0]['id'] ) );\n\t\t$request->set_param( 'context', 'view' );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$get_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $get_data[0]['foo_group_key'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n\n\t/**\n\t * @group additional_fields\n\t */\n\tpublic function test_update_additional_fields() {\n\t\t$registered_fields = $GLOBALS['wp_rest_additional_fields'];\n\n\t\tbp_rest_register_field( 'xprofile', 'bar_group_key', array(\n\t\t\t'get_callback'    => array( $this, 'get_additional_field' ),\n\t\t\t'update_callback' => array( $this, 'update_additional_field' ),\n\t\t\t'schema'          => array(\n\t\t\t\t'description' => 'xProfile Group Meta Field',\n\t\t\t\t'type'        => 'string',\n\t\t\t\t'context'     => array( 'view', 'edit' ),\n\t\t\t),\n\t\t), 'group' );\n\n\t\t$this->bp::set_current_user( $this->user );\n\t\t$expected = 'foo_group_value';\n\n\t\t// PUT\n\t\t$request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $this->group_id ) );\n\t\t$request->add_header( 'content-type', 'application/json' );\n\t\t$request->set_body( wp_json_encode(\n\t\t\tarray(\n\t\t\t\t'name'          => $this->endpoint->get_xprofile_field_group_object( $this->group_id )->name,\n\t\t\t\t'bar_group_key' => $expected,\n\t\t\t)\n\t\t) );\n\t\t$response = $this->server->dispatch( $request );\n\n\t\t$update_data = $response->get_data();\n\t\t$this->assertTrue( $expected === $update_data[0]['bar_group_key'] );\n\n\t\t$GLOBALS['wp_rest_additional_fields'] = $registered_fields;\n\t}\n}\n"
  },
  {
    "path": "wp-env.json",
    "content": "{\n  \"core\": \"WordPress/WordPress#master\",\n  \"plugins\": [\"buddypress/buddypress#master\", \".\"],\n  \"config\": {\n    \"WP_DEBUG\": true,\n    \"SCRIPT_DEBUG\": true\n  }\n}\n"
  }
]