namespace, '/search', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'permission_community' ), 'args' => array( 'q' => array( 'type' => 'string', 'required' => true, 'sanitize_callback' => 'sanitize_text_field', ), 'type' => array( 'type' => 'string', 'enum' => array( 'all', 'posts', 'spaces', 'members' ), 'default' => 'all', ), 'page' => array( 'type' => 'integer', 'default' => 1, 'minimum' => 1, ), ), ), ) ); } /** * Runs a search. * * @param WP_REST_Request $request Request. * @return WP_REST_Response|WP_Error */ public function get_items( $request ) { $query = trim( (string) $request['q'] ); if ( mb_strlen( $query ) < 2 ) { return new WP_Error( 'spacebay_search_short', __( 'Type at least two characters.', 'spacebay' ), array( 'status' => 400 ) ); } $query = mb_substr( $query, 0, 100 ); $type = $request['type']; $per_page = 'all' === $type ? 5 : 20; $page = 'all' === $type ? 1 : (int) $request['page']; $viewer_id = SpaceAccess::effective_id( get_current_user_id() ); $result = array(); if ( 'all' === $type || 'posts' === $type ) { $posts = Posts::query( array( 'search' => $query, 'page' => $page, 'per_page' => $per_page, // The apps only need to know whether there are more results. 'count' => false, ), $viewer_id ); $result['posts'] = array( 'items' => Formatter::posts( $posts['items'], $viewer_id ), 'total' => $posts['total'], ); } if ( 'all' === $type || 'spaces' === $type ) { $spaces = array(); foreach ( SpaceRepository::all( 'space' ) as $space ) { $haystack = $space['title'] . ' ' . $space['description']; if ( false !== mb_stripos( $haystack, $query ) && SpaceAccess::can_see( $space, $viewer_id ) ) { $spaces[] = $space; } } $result['spaces'] = array( 'items' => array_map( static function ( $space ) use ( $viewer_id ) { return SpaceFormatter::space( $space, $viewer_id ); }, array_slice( $spaces, ( $page - 1 ) * $per_page, $per_page ) ), 'total' => count( $spaces ), ); } if ( ( 'all' === $type || 'members' === $type ) && $this->can_search_members( $viewer_id ) ) { $result['members'] = MemberDirectory::query( array( 'search' => $query, 'page' => $page, 'per_page' => $per_page, 'orderby' => 'name', ) ); } return rest_ensure_response( $result ); } /** * Members appear in search for logged-in viewers when the directory is on. * * @param int $viewer_id Viewer. * @return bool */ private function can_search_members( $viewer_id ) { return $viewer_id > 0 && ( 'off' !== Settings::get( 'member_directory' ) || SpaceAccess::is_manager( $viewer_id ) ); } }