BP_REST_Groups_Details_Endpoint

Groups Details endpoints.

Description

Source

File: bp-groups/classes/class-bp-rest-groups-details-endpoint.php

class BP_REST_Groups_Details_Endpoint extends WP_REST_Controller {

	/**
	 * BP_REST_Groups_Endpoint Instance.
	 *
	 * @var BP_REST_Groups_Endpoint
	 */
	protected $groups_endpoint;

	/**
	 * Constructor.
	 *
	 * @since 0.1.0
	 */
	public function __construct() {
		$this->namespace       = bp_rest_namespace() . '/' . bp_rest_version();
		$this->rest_base       = buddypress()->groups->id;
		$this->groups_endpoint = new BP_REST_Groups_Endpoint();
	}

	/**
	 * Register the component routes.
	 *
	 * @since 0.1.0
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/details',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_items' ),
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
					'args'                => $this->get_collection_params(),
				),
				'schema' => array( $this, 'get_item_schema' ),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/(?P<id>[\d]+)/detail',
			array(
				'args'   => array(
					'id' => array(
						'description' => __( 'A unique numeric ID for the Group.', 'buddyboss' ),
						'type'        => 'integer',
					),
				),
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_item' ),
					'permission_callback' => array( $this, 'get_item_permissions_check' ),
				),
				'schema' => array( $this, 'get_item_schema' ),
			)
		);
	}

	/**
	 * Retrieve groups details.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response | WP_Error List of groups object data.
	 * @since 0.1.0
	 *
	 * @api            {GET} /wp-json/buddyboss/v1/groups/details Groups Details
	 * @apiName        GetBBGroupsDetails
	 * @apiGroup       Groups
	 * @apiDescription Retrieve groups details(includes tabs and order_options)
	 * @apiVersion     1.0.0
	 *
	 * @apiParam {String=active,popular,newest,alphabetical} [type] Reorder group by type.
	 */
	public function get_items( $request ) {
		$retval = array();

		$retval['tabs']          = $this->get_groups_tabs( $request );
		$retval['order_options'] = bp_nouveau_get_component_filters( 'group', 'groups' );

		$response = rest_ensure_response( $retval );

		/**
		 * Fires after a list of groups details is fetched via the REST API.
		 *
		 * @param WP_REST_Response $response The response data.
		 * @param WP_REST_Request  $request  The request sent to the API.
		 *
		 * @since 0.1.0
		 */
		do_action( 'bp_rest_groups_get_items', $response, $request );

		return $response;
	}

	/**
	 * Check if a given request has access to group details.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return bool|WP_Error
	 * @since 0.1.0
	 */
	public function get_items_permissions_check( $request ) {
		$retval = true;

		if ( ! bp_is_active( 'groups' ) ) {
			$retval = new WP_Error(
				'bp_rest_component_required',
				__( 'Sorry, Groups component was not enabled.', 'buddyboss' ),
				array(
					'status' => '404',
				)
			);
		}

		/**
		 *  Filter the group details permissions check.
		 *
		 * @param bool|WP_Error   $retval  Returned value.
		 * @param WP_REST_Request $request The request sent to the API.
		 *
		 * @since 0.1.0
		 */
		return apply_filters( 'bp_rest_group_details_get_items_permissions_check', $retval, $request );
	}

	/**
	 * Retrieve groups detail.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response | WP_Error List of groups object data.
	 * @since 0.1.0
	 *
	 * @api            {GET} /wp-json/buddyboss/v1/groups/:id/detail Group Detail
	 * @apiName        GetBBGroupsDetail
	 * @apiGroup       Groups
	 * @apiDescription Retrieve groups detail tabs.
	 * @apiVersion     1.0.0
	 * @apiPermission  LoggedInUser if the site is in Private Network.
	 * @apiParam {Number} id A unique numeric ID for the Group.
	 */
	public function get_item( $request ) {

		global $bp;

		$retval = array();
		$group  = $this->groups_endpoint->get_group_object( $request );

		if ( empty( $group->id ) ) {
			$retval = new WP_Error(
				'bp_rest_group_invalid_id',
				__( 'Invalid group ID.', 'buddyboss' ),
				array(
					'status' => 404,
				)
			);
		}

		/**
		 * Store temporary variable
		 */
		$url     = ( '/' . bp_get_groups_root_slug() . '/' . bp_get_group_slug( $group ) );
		$tempurl = ( ! empty( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' );
		$tmp_bp  = $bp;

		/**
		 * Group navigation tabs creation start
		 *
		 * Groups Navigation tab only setup on group page request so for fetch group tabs we need set group url as `REQUEST_URI` forcefully and
		 * Once our job done switch back to original url.
		 * With below process BuddyPress state might be change so we need to rest it once our job done.
		 *
		 * After set Group url forcefully we need to re-execute core hook which load component and setup tabs for given group.
		 */
		$_SERVER['REQUEST_URI'] = $url;

		// Fixes for the phpunit.
		add_filter( 'bp_loggedin_user_id', array( $this, 'bp_rest_get_displayed_user' ), 999 );
		add_filter( 'bp_displayed_user_id', array( $this, 'bp_rest_get_displayed_user' ), 999 );

		remove_action( 'bp_init', 'bp_register_taxonomies', 2 );
		remove_action( 'bp_init', 'bp_register_post_types', 2 );
		remove_action( 'bp_init', 'bp_setup_title', 8 );
		remove_action( 'bp_init', 'bp_core_load_admin_bar_css', 12 );
		remove_action( 'bp_init', 'bp_add_rewrite_tags', 20 );
		remove_action( 'bp_init', 'bp_add_rewrite_rules', 30 );
		remove_action( 'bp_init', 'bp_add_permastructs', 40 );
		remove_action( 'bp_init', 'bp_init_background_updater', 50 );
		remove_all_actions( 'bp_actions' );

		do_action( 'bp_init' );
		// phpcs:ignore
		do_action( 'bp_ld_sync/init' ); // We should remove when platform load learndash extention on bp_init.
		do_action( 'bp_actions' );

		add_action( 'bp_init', 'bp_register_taxonomies', 2 );
		add_action( 'bp_init', 'bp_register_post_types', 2 );
		add_action( 'bp_init', 'bp_setup_title', 8 );
		add_action( 'bp_init', 'bp_core_load_admin_bar_css', 12 );
		add_action( 'bp_init', 'bp_add_rewrite_tags', 20 );
		add_action( 'bp_init', 'bp_add_rewrite_rules', 30 );
		add_action( 'bp_init', 'bp_add_permastructs', 40 );
		add_action( 'bp_init', 'bp_init_background_updater', 50 );

		$group_slug = $group->slug;

		$group_nav = buddypress()->groups->nav;
		bp_nouveau_set_nav_item_order( $group_nav, bp_nouveau_get_appearance_settings( 'group_nav_order' ), $group_slug );

		$navigation  = array();
		$default_tab = 'members';

		if ( function_exists( 'bp_nouveau_get_appearance_settings' ) ) {
			$default_tab = bp_nouveau_get_appearance_settings( 'group_default_tab' );
		}

		$nav_items = $group_nav->get_secondary(
			array(
				'parent_slug'     => $group_slug,
				'user_has_access' => true,
			)
		);

		if ( ! empty( $nav_items ) ) {
			foreach ( $nav_items as $nav ) {
				$nav = $nav->getArrayCopy();

				if ( 'public' !== $group->status && $nav['slug'] === 'courses' && ( ! groups_is_user_member( bp_loggedin_user_id(), $group->id ) && ! bp_current_user_can( 'bp_moderate' ) ) ) {
					continue;
				}

				$name = $nav['name'];
				$id   = $nav['slug'];

				// remove the count numbers.
				$name = preg_replace( '/^(.*)(<(.*)<\/(.*)>)/', '$1', $name );
				$name = trim( $name );

				$tab = array(
					'id'              => $id,
					'title'           => $name,
					'count'           => $this->bp_rest_get_nav_count( $group, $nav ),
					'position'        => $nav['position'],
					'default'         => false,
					'user_has_access' => $nav['user_has_access'],
					'link'            => $nav['link'],
					'children'        => '',
				);

				if ( $default_tab === $nav['slug'] ) {
					$tab['default'] = true;
				}

				$parent_slug = $group_slug;

				if ( 'admin' === $nav['slug'] ) {
					$parent_slug .= '_manage';
				} elseif ( 'invite' === $nav['slug'] ) {
					$parent_slug .= '_invite';
				} elseif ( 'photos' === $nav['slug'] ) {
					$parent_slug .= '_media';
				} elseif ( 'members' === $nav['slug'] ) {
					$parent_slug .= '_members';
				}

				$sub_navs = array();

				if ( $group_slug !== $parent_slug ) {
					$sub_items = $group_nav->get_secondary(
						array(
							'parent_slug'     => $parent_slug,
							'user_has_access' => true,
						)
					);

					if ( ! empty( $sub_items ) ) {
						foreach ( $sub_items as $sub_nav ) {
							$sub_nav = $sub_nav->getArrayCopy();

							$sub_name = $sub_nav['name'];
							$sub_id   = $sub_nav['slug'];

							// remove the count numbers.
							$sub_name = preg_replace( '/^(.*)(<(.*)<\/(.*)>)/', '$1', $sub_name );
							$sub_name = trim( $sub_name );

							$sub_navs[] = array(
								'id'              => $sub_id,
								'title'           => $sub_name,
								'count'           => $this->bp_rest_get_nav_count( $group, $sub_nav ),
								'position'        => $sub_nav['position'],
								'default'         => false,
								'user_has_access' => $sub_nav['user_has_access'],
								'link'            => $sub_nav['link'],
								'children'        => '',
							);
						}
					}
				}

				$tab['children'] = $sub_navs;
				$navigation[]    = apply_filters( 'bp_rest_group_tab_' . $id, $tab, $nav );
			}
		}

		$retval['tabs'] = $navigation;

		// Fixes for the phpunit.
		remove_filter( 'bp_displayed_user_id', array( $this, 'bp_rest_get_displayed_user' ), 999 );
		remove_filter( 'bp_loggedin_user_id', array( $this, 'bp_rest_get_displayed_user' ), 999 );

		/**
		 * Group navigation tabs creation End
		 *
		 * Switching back to original `REQUEST_URI` and BuddyPress stat.
		 */
		$_SERVER['REQUEST_URI'] = $tempurl;
		$bp                     = $tmp_bp;

		$response = rest_ensure_response( $retval );

		/**
		 * Fires after a list of groups details is fetched via the REST API.
		 *
		 * @param WP_REST_Response $response The response data.
		 * @param WP_REST_Request  $request  The request sent to the API.
		 *
		 * @since 0.1.0
		 */
		do_action( 'bp_rest_groups_get_item', $response, $request );

		return $response;
	}

	/**
	 * Check if a given request has access to group details.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return bool|WP_Error
	 * @since 0.1.0
	 */
	public function get_item_permissions_check( $request ) {
		$retval = true;

		if ( function_exists( 'bp_enable_private_network' ) && true !== bp_enable_private_network() && ! is_user_logged_in() ) {
			$retval = new WP_Error(
				'bp_rest_authorization_required',
				__( 'Sorry, Restrict access to only logged-in members.', 'buddyboss' ),
				array(
					'status' => rest_authorization_required_code(),
				)
			);
		}

		if ( true === $retval && ! bp_is_active( 'groups' ) ) {
			$retval = new WP_Error(
				'bp_rest_component_required',
				__( 'Sorry, Groups component was not enabled.', 'buddyboss' ),
				array(
					'status' => '404',
				)
			);
		}

		$group = $this->groups_endpoint->get_group_object( $request );
		if ( true === $retval && empty( $group->id ) ) {
			$retval = new WP_Error(
				'bp_rest_group_invalid_id',
				__( 'Invalid group ID.', 'buddyboss' ),
				array(
					'status' => 404,
				)
			);
		}

		if ( true === $retval && ! is_user_logged_in() && ( 'private' === bp_get_group_status( $group ) || 'hidden' === bp_get_group_status( $group ) ) ) {
			$retval = new WP_Error(
				'bp_rest_authorization_required',
				__( 'Sorry, you are not allowed to view group tabs.', 'buddyboss' ),
				array(
					'status' => rest_authorization_required_code(),
				)
			);
		}

		/**
		 *  Filter the group detail permissions check.
		 *
		 * @param bool|WP_Error   $retval  Returned value.
		 * @param WP_REST_Request $request The request sent to the API.
		 *
		 * @since 0.1.0
		 */
		return apply_filters( 'bp_rest_group_details_get_items_permissions_check', $retval, $request );
	}

	/**
	 * Get the group details schema, conforming to JSON Schema.
	 *
	 * @return array
	 * @since 0.1.0
	 */
	public function get_item_schema() {
		$schema = array(
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
			'title'      => 'bp_groups_details',
			'type'       => 'object',
			'properties' => array(
				'tabs'          => array(
					'context'     => array( 'embed', 'view' ),
					'description' => __( 'Groups directory tabs.', 'buddyboss' ),
					'type'        => 'object',
					'readonly'    => true,
					'items'       => array(
						'type' => 'array',
					),
				),
				'order_options' => array(
					'context'     => array( 'embed', 'view' ),
					'description' => __( 'Groups order by options.', 'buddyboss' ),
					'type'        => 'array',
					'readonly'    => true,
				),
			),
		);

		/**
		 * Filters the group details schema.
		 *
		 * @param array $schema The endpoint schema.
		 */
		return apply_filters( 'bp_rest_group_schema', $this->add_additional_fields_schema( $schema ) );
	}

	/**
	 * Get the query params for collections of plugins.
	 *
	 * @return array
	 * @since 0.1.0
	 */
	public function get_collection_params() {
		$params = array(
			'type' => array(
				'description'       => __( 'Filter by.. active(Last Active), popular(Most Members), newest(Newly Created), alphabetical(Alphabetical)', 'buddyboss' ),
				'type'              => 'string',
				'enum'              => array( 'active', 'popular', 'newest', 'alphabetical' ),
				'validate_callback' => 'rest_validate_request_arg',
			),
		);

		/**
		 * Filters the collection query params.
		 *
		 * @param array $params Query params.
		 */
		return apply_filters( 'bp_rest_groups_details_collection_params', $params );
	}

	/**
	 * Get Groups tabs.
	 *
	 * @param WP_REST_Request $request The request sent to the API.
	 *
	 * @return array
	 */
	public function get_groups_tabs( $request ) {
		$type = $request->get_param( 'type' );
		$tabs = array();

		$tabs_items = bp_nouveau_get_groups_directory_nav_items();

		if ( ! empty( $tabs_items ) ) {
			foreach ( $tabs_items as $key => $item ) {
				$tabs[ $key ]['title']    = $item['text'];
				$tabs[ $key ]['position'] = $item['position'];
				$tabs[ $key ]['count']    = $this->get_group_tab_count( $item['slug'], $type );
			}
		}

		return $tabs;
	}

	/**
	 * Get group count for the tab.
	 *
	 * @param sting  $slug Group tab object slug.
	 * @param string $type Active, newest, alphabetical, random, popular.
	 *
	 * @return int
	 */
	protected function get_group_tab_count( $slug, $type ) {
		$count   = 0;
		$user_id = ! empty( get_current_user_id() ) ? ( get_current_user_id() ) : false;

		switch ( $slug ) {
			case 'all':
				$groups = groups_get_groups( array( 'type' => $type ) );
				if ( ! empty( $groups ) && isset( $groups['total'] ) ) {
					$count = $groups['total'];
				}
				break;
			case 'personal':
				$groups = groups_get_groups(
					array(
						'type'    => $type,
						'user_id' => $user_id,
					)
				);
				if ( ! empty( $groups ) && isset( $groups['total'] ) ) {
					$count = $groups['total'];
				}
				break;
		}

		return $count;
	}

	/**
	 * Retrieve the count attribute for the current nav item.
	 *
	 * @param BP_Groups_Group $group Optional. Group object. Default: current group in loop.
	 * @param array           $nav   Navigation array.
	 *
	 * @return int The count attribute for the nav item.
	 */
	protected function bp_rest_get_nav_count( $group, $nav ) {
		$nav_item = $nav['slug'];

		if ( 'members' === $nav_item || 'all-members' === $nav_item ) {
			$count = $group->total_member_count;
		} elseif ( 'subgroups' === $nav_item ) {
			$count = count( bp_get_descendent_groups( $group->id, bp_loggedin_user_id() ) );
		} elseif ( bp_is_active( 'media' ) && bp_is_group_media_support_enabled() && 'photos' === $nav_item && function_exists( 'bp_is_group_media_support_enabled' ) ) {
			$count = bp_media_get_total_group_media_count( $group->id );
		} elseif ( bp_is_active( 'media' ) && bp_is_group_albums_support_enabled() && 'albums' === $nav_item && function_exists( 'bp_is_group_albums_support_enabled' ) ) {
			$count = bp_media_get_total_group_album_count( $group->id );
		} elseif ( 'leaders' === $nav_item ) {
			$admins = groups_get_group_admins( $group->id );
			$mods   = groups_get_group_mods( $group->id );
			$count  = count( $admins ) + count( $mods );
		}

		if ( ! isset( $count ) ) {
			return false;
		}

		return $count;
	}

	/**
	 * Set current and display user with current user.
	 *
	 * @param int $user_id The user id.
	 *
	 * @return int
	 */
	public function bp_rest_get_displayed_user( $user_id ) {
		return get_current_user_id();
	}
}

Changelog

Changelog
Version Description
0.1.0 Introduced.

Methods

Questions?

We're always happy to help with code or other questions you might have! Search our developer docs, contact support, or connect with our sales team.