Skip to:
Content

BuddyPress.org

Ticket #3278: master...suggestions.patch

File master...suggestions.patch, 108.2 KB (added by DJPaul, 10 years ago)

v1

  • src/bp-core/bp-core-functions.php

    From 3c4b6b991f7a882a1567122698678a115a47376d Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 13:34:35 +0100
    Subject: [PATCH 01/35] Add current Suggestions API work.
    
    ---
     src/bp-core/bp-core-functions.php                  |  70 ++++
     src/bp-members/bp-members-filters.php              |  13 +
     src/bp-members/bp-members-functions.php            |  62 ++++
     .../phpunit/testcases/apis/suggestions-nonauth.php | 107 ++++++
     tests/phpunit/testcases/apis/suggestions.php       | 386 +++++++++++++++++++++
     5 files changed, 638 insertions(+)
     create mode 100644 tests/phpunit/testcases/apis/suggestions-nonauth.php
     create mode 100644 tests/phpunit/testcases/apis/suggestions.php
    
    diff --git a/src/bp-core/bp-core-functions.php b/src/bp-core/bp-core-functions.php
    index 9e46100..75cb9f5 100644
    a b function bp_nav_menu_get_item_url( $slug ) { 
    19211921
    19221922        return $nav_item_url;
    19231923}
     1924
     1925/** Suggestions***************************************************************/
     1926
     1927/**
     1928 * BuddyPress Suggestions API for types of at-mentions.
     1929 *
     1930 * This is used to power BuddyPress' at-mentions suggestions, but it is flexible enough to be used
     1931 * for similar kinds of requirements.
     1932 *
     1933 * If a Component or a third-party plugin wants to provide suggestions for a custom type of object,
     1934 * use the bp_suggestions_get_types filter and return an associative array with its key as the new
     1935 * "type", and its value as a function callback.
     1936 *
     1937 * The callback must validate any custom requirements in $args and fetch results that match $term
     1938 * in some relevant way. If validation fails, a WP_Error object must be returned. If no matches are
     1939 * found, an empty array must be returned. Matches must be returned as objects in an array.
     1940 *
     1941 * The object format for each match must be: { 'ID': string, 'image': string, 'name': string }
     1942 * For example: { 'ID': 'admin', 'image': 'http://example.com/logo.png', 'name': 'Name Surname' }
     1943 *
     1944 * @param array $args {
     1945 *     @type int limit Maximum number of results to display. Default: 16.
     1946 *     @type int|string $object_id Specifies a particular object that may be used by a suggestion
     1947 *           service. Accepts either an integer or a string. For example, this could be used by a
     1948 *           Groups suggestion type that searches for members who are members of a specific group.
     1949 *     @type string $type The name of the suggestion service to use for the request. Mandatory.
     1950 *     @type string $term The suggestion service will try to find results that contain this string.
     1951 *           Mandatory.
     1952 * }
     1953 * @return array|WP_Error Array of results. If there were any problems, returns a WP_Error object.
     1954 * @since BuddyPress (2.1.0)
     1955 */
     1956function bp_core_get_suggestions( $args ) {
     1957        $defaults = array(
     1958                'limit'     => 16,
     1959                'object_id' => 0,
     1960                'type'      => '',
     1961                'term'      => '',
     1962        );
     1963        $args = wp_parse_args( $args, $defaults );
     1964
     1965        if ( ctype_digit( $args['object_id'] ) ) {
     1966                $args['object_id'] = absint( $args['object_id'] );
     1967        } else {
     1968                $args['object_id'] = sanitize_text_field( $args['object_id'] );
     1969        }
     1970
     1971        $args['limit'] = absint( $args['limit'] );
     1972        $args['term']  = trim( sanitize_text_field( $args['term'] ) );
     1973
     1974        $args      = apply_filters( 'bp_suggestions_args', $args );
     1975        $callbacks = apply_filters( 'bp_suggestions_get_types', array() );
     1976
     1977        if ( ! in_array( $args['type'], array_keys( $callbacks ) ) ) {
     1978                $args['type'] = null;
     1979        }
     1980
     1981        if ( ! $args['limit'] || is_null( $args['type'] ) || ! is_callable( $callbacks[ $args['type'] ] ) || ! $args['term'] ) {
     1982                // Invalid or missing mandatory parameter.
     1983                return new WP_Error( 'missing_parameter' );
     1984        }
     1985
     1986        if ( is_user_logged_in() && ! bp_is_user_active( get_current_user_id() ) ) {
     1987                // Blocked user account (e.g. deleted or spammer).
     1988                return new WP_Error( 'invalid_user' );
     1989        }
     1990
     1991        $results = call_user_func( $callbacks[ $args['type'] ], $args );
     1992        return apply_filters( 'bp_core_get_suggestions', $results, $args );
     1993}
     1994 No newline at end of file
  • src/bp-members/bp-members-filters.php

    diff --git a/src/bp-members/bp-members-filters.php b/src/bp-members/bp-members-filters.php
    index fed76b6..3c0c610 100644
    a b function bp_members_edit_profile_url( $url, $user_id, $scheme = 'admin' ) { 
    7777        return apply_filters( 'bp_members_edit_profile_url', $profile_link, $url, $user_id, $scheme );
    7878}
    7979add_filter( 'edit_profile_url', 'bp_members_edit_profile_url', 10, 3 );
     80
     81/**
     82 * Add support for @username mentions to BuddyPress.
     83 *
     84 * @param array $types Array of registered extensions to the Suggestion API.
     85 * @return array
     86 * @see bp_core_get_suggestions()
     87 */
     88function bp_members_register_suggestion_types( $types ) {
     89        $types['members'] = 'bp_members_get_suggestions';
     90        return $types;
     91}
     92add_filter( 'bp_suggestions_get_types', 'bp_members_register_suggestion_types' );
  • src/bp-members/bp-members-functions.php

    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 6e6a529..6e28ec3 100644
    a b function bp_live_spammer_login_error() { 
    20852085        add_action( 'login_head', 'wp_shake_js', 12 );
    20862086}
    20872087add_action( 'login_form_bp-spam', 'bp_live_spammer_login_error' );
     2088
     2089/**
     2090 * Implement support for @username mentions.
     2091 *
     2092 * The $args parameter may include other parameters not documented here; if so, they are not used
     2093 * by this particular Suggestions API extension.
     2094 *
     2095 * @param array $args {
     2096 *     @type int limit Maximum number of results to display. Default: 16.
     2097 *     @type string $term The suggestion service will try to find results that contain this string.
     2098 *           Mandatory.
     2099 * }
     2100 * @return array|WP_Error See {@see bp_core_get_suggestions()}. If any problems, return a WP_Error.
     2101 * @see bp_core_get_suggestions()
     2102 * @since BuddyPress (2.1.0)
     2103 */
     2104function bp_members_get_suggestions( $args ) {
     2105        $defaults = array(
     2106                'limit'        => 16,     // Sanitised upstream
     2107                'only_friends' => false,
     2108                'term'         => '',     // Sanitised upstream
     2109        );
     2110        $args = apply_filters( 'bp_members_get_suggestions_args', wp_parse_args( $args, $defaults ) );
     2111
     2112        if ( $args['only_friends'] && ! bp_is_active( 'friends' ) ) {
     2113                // Friends component is missing.
     2114                return new WP_Error( 'missing_requirement' );
     2115        }
     2116
     2117        $user_query = array(
     2118                'count_total'     => '',  // Prevents total count
     2119                'populate_extras' => false,
     2120                'type'            => 'alphabetical',
     2121
     2122                'page'            => 1,
     2123                'per_page'        => $args['limit'],
     2124                'search_terms'    => $args['term'],
     2125        );
     2126
     2127        if ( $args['only_friends'] ) {
     2128                $user_query['user_id'] = get_current_user_id();
     2129        }
     2130
     2131
     2132        $user_query = new BP_User_Query( $user_query );
     2133        $results    = array();
     2134
     2135        foreach ( $user_query->results as $user ) {
     2136                $result        = new stdClass();
     2137                $result->ID    = $user->user_nicename;
     2138                $result->image = get_avatar( $user );
     2139                $result->name  = $user->display_name;
     2140
     2141                if ( bp_disable_profile_sync() ) {
     2142                        $result->name = BP_XProfile_Field::get_fullname( $user->ID );
     2143                }
     2144
     2145                $results[] = $result;
     2146        }
     2147
     2148        return apply_filters( 'bp_members_get_suggestions', $results, $args );
     2149}
     2150 No newline at end of file
  • new file tests/phpunit/testcases/apis/suggestions-nonauth.php

    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    new file mode 100644
    index 0000000..0e1be23
    - +  
     1<?php
     2/**
     3 * Suggestions API tests specifically for non-authenticated (anonymous) users.
     4 *
     5 * @group api
     6 * @group suggestions
     7 */
     8class BP_Tests_Suggestions_Non_Authenticated extends BP_UnitTestCase {
     9        protected $group_ids    = array();
     10        protected $group_slugs  = array();
     11        protected $user_ids     = array();
     12
     13        public function setUp() {
     14                parent::setUp();
     15
     16                $users = array(
     17                        // user_login, display_name
     18                        array( 'aardvark',    'Bob Smith' ),
     19                        array( 'alpaca red',  'William Quinn' ),
     20                        array( 'cat',         'Lauren Curtis' ),
     21                        array( 'caterpillar', 'Eldon Burrows' ),
     22                        array( 'dog green',   'Reece Thornton' ),
     23                        array( 'pig',         'Joshua Barton' ),
     24                        array( 'rabbit blue', 'Amber Hooper' ),
     25                        array( 'smith',       'Robert Bar' ),
     26                        array( 'snake',       'Eleanor Moore' ),
     27                        array( 'zoom',        'Lisa Smithy' ),
     28                );
     29
     30                // Create some dummy users.
     31                foreach( $users as $user ) {
     32                        $this->user_ids[ $user[0] ] = $this->factory->user->create( array(
     33                                'display_name' => $user[1],
     34                                'user_login'   => $user[0],
     35                        ) );
     36                }
     37
     38                $this->group_slugs['hidden']  = 'the-maw';
     39                $this->group_slugs['public']  = 'the-great-journey';
     40                $this->group_slugs['private'] = 'tsavo-highway';
     41
     42                // Create dummy groups.
     43                $this->group_ids['hidden']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['hidden'],  'status' => 'hidden' ) );
     44                $this->group_ids['public']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['public'],  'status' => 'public' ) );
     45                $this->group_ids['private'] = $this->factory->group->create( array( 'slug' => $this->group_slugs['private'], 'status' => 'private' ) );
     46
     47                // Add dummy users to dummy hidden groups.
     48                groups_join_group( $this->group_ids['hidden'], $this->user_ids['pig'] );
     49                groups_join_group( $this->group_ids['hidden'], $this->user_ids['alpaca red'] );
     50
     51                // Add dummy users to dummy public groups.
     52                groups_join_group( $this->group_ids['public'], $this->user_ids['aardvark'] );
     53                groups_join_group( $this->group_ids['public'], $this->user_ids['smith'] );
     54
     55                // Add dummy users to dummy private groups.
     56                groups_join_group( $this->group_ids['private'], $this->user_ids['cat'] );
     57                groups_join_group( $this->group_ids['private'], $this->user_ids['caterpillar'] );
     58        }
     59
     60
     61        /**
     62         * Tests below this point are expected to fail.
     63         */
     64
     65        public function test_suggestions_with_type_members_and_only_friends() {
     66                // only_friends requires authenticated requests
     67                $suggestions = bp_core_get_suggestions( array(
     68                        'only_friends' => true,
     69                        'type'         => 'members',
     70                        'term'         => 'smith',
     71                ) );
     72
     73                $this->assertTrue( is_wp_error( $suggestions ) );
     74        }
     75
     76        public function test_suggestions_with_type_group_and_only_friends() {
     77                // only_friends requires authenticated requests
     78                $suggestions = bp_core_get_suggestions( array(
     79                        'object_id'    => $this->group_ids['public'],
     80                        'only_friends' => true,
     81                        'type'         => 'group-members',
     82                        'term'         => 'smith',
     83                ) );
     84
     85                $this->assertTrue( is_wp_error( $suggestions ) );
     86        }
     87
     88        public function test_suggestions_with_type_group_hidden() {
     89                $suggestions = bp_core_get_suggestions( array(
     90                        'object_id' => $this->group_ids['hidden'],
     91                        'type'      => 'group-members',
     92                        'term'      => 'pig',
     93                ) );
     94
     95                $this->assertTrue( is_wp_error( $suggestions ) );
     96        }
     97
     98        public function test_suggestions_with_type_group_private() {
     99                $suggestions = bp_core_get_suggestions( array(
     100                        'object_id' => $this->group_ids['private'],
     101                        'type'      => 'group-members',
     102                        'term'      => 'cat',
     103                ) );
     104
     105                $this->assertTrue( is_wp_error( $suggestions ) );
     106        }
     107}
     108 No newline at end of file
  • new file tests/phpunit/testcases/apis/suggestions.php

    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    new file mode 100644
    index 0000000..7fc85d7
    - +  
     1<?php
     2/**
     3 * Suggestions API tests for authenticated (logged in) users.
     4 *
     5 * @group api
     6 * @group suggestions
     7 */
     8class BP_Tests_Suggestions_Authenticated extends BP_UnitTestCase {
     9        protected $current_user = null;
     10        protected $group_ids    = array();
     11        protected $group_slugs  = array();
     12        protected $old_user_id  = 0;
     13        protected $user_ids     = array();
     14
     15        public function setUp() {
     16                parent::setUp();
     17
     18                $this->old_user_id  = get_current_user_id();
     19                $this->current_user = $this->factory->user->create( array(
     20                        'display_name' => 'Katie Parker',
     21                        'user_login'   => 'admin',
     22                ) );
     23
     24                $this->set_current_user( $this->current_user );
     25
     26                $users = array(
     27                        // user_login, display_name
     28                        array( 'aardvark',    'Bob Smith' ),
     29                        array( 'alpaca red',  'William Quinn' ),
     30                        array( 'cat',         'Lauren Curtis' ),
     31                        array( 'caterpillar', 'Eldon Burrows' ),
     32                        array( 'dog green',   'Reece Thornton' ),
     33                        array( 'pig',         'Joshua Barton' ),
     34                        array( 'rabbit blue', 'Amber Hooper' ),
     35                        array( 'smith',       'Robert Bar' ),
     36                        array( 'snake',       'Eleanor Moore' ),
     37                        array( 'zoom',        'Lisa Smithy' ),
     38                );
     39
     40                // Create some dummy users.
     41                foreach( $users as $user ) {
     42                        $this->user_ids[ $user[0] ] = $this->factory->user->create( array(
     43                                'display_name' => $user[1],
     44                                'user_login'   => $user[0],
     45                        ) );
     46                }
     47
     48                // Create some dummy friendships.
     49                friends_add_friend( $this->current_user, $this->user_ids['aardvark'], true );
     50                friends_add_friend( $this->current_user, $this->user_ids['cat'], true );
     51                friends_add_friend( $this->current_user, $this->user_ids['caterpillar'], true );
     52                friends_add_friend( $this->current_user, $this->user_ids['pig'], true );
     53
     54                $this->group_slugs['hidden']  = 'the-maw';
     55                $this->group_slugs['public']  = 'the-great-journey';
     56                $this->group_slugs['private'] = 'tsavo-highway';
     57
     58                // Create dummy groups.
     59                $this->group_ids['hidden']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['hidden'],  'status' => 'hidden' ) );
     60                $this->group_ids['public']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['public'],  'status' => 'public' ) );
     61                $this->group_ids['private'] = $this->factory->group->create( array( 'slug' => $this->group_slugs['private'], 'status' => 'private' ) );
     62
     63                // Add dummy users to dummy hidden groups.
     64                groups_join_group( $this->group_ids['hidden'], $this->user_ids['pig'] );
     65                groups_join_group( $this->group_ids['hidden'], $this->user_ids['alpaca red'] );
     66
     67                // Add dummy users to dummy public groups.
     68                groups_join_group( $this->group_ids['public'], $this->current_user );
     69                groups_join_group( $this->group_ids['public'], $this->user_ids['aardvark'] );
     70                groups_join_group( $this->group_ids['public'], $this->user_ids['smith'] );
     71
     72                // Add dummy users to dummy private groups.
     73                groups_join_group( $this->group_ids['private'], $this->user_ids['cat'] );
     74                groups_join_group( $this->group_ids['private'], $this->user_ids['caterpillar'] );
     75        }
     76
     77        public function tearDown() {
     78                parent::tearDown();
     79                $this->set_current_user( $this->old_user_id );
     80        }
     81
     82
     83        public function test_suggestions_with_type_members() {
     84                $suggestions = bp_core_get_suggestions( array(
     85                        'type' => 'members',
     86                        'term' => 'smith',
     87                ) );
     88
     89                $this->assertEquals( 3, count( $suggestions ) );  // aardvark, smith, zoom.
     90        }
     91
     92        public function test_suggestions_with_type_members_and_limit() {
     93                $suggestions = bp_core_get_suggestions( array(
     94                        'limit' => 2,
     95                        'type'  => 'members',
     96                        'term'  => 'smith',
     97                ) );
     98
     99                $this->assertEquals( 2, count( $suggestions ) );  // two of: aardvark, smith, zoom.
     100        }
     101
     102        public function test_suggestions_with_type_members_and_only_friends() {
     103                $suggestions = bp_core_get_suggestions( array(
     104                        'only_friends' => true,
     105                        'type'         => 'members',
     106                        'term'         => 'smith',
     107                ) );
     108                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
     109
     110                $suggestions = bp_core_get_suggestions( array(
     111                        'only_friends' => true,
     112                        'type'         => 'members',
     113                        'term'         => 'cat',
     114                ) );
     115                $this->assertEquals( 2, count( $suggestions ) );  // cat, caterpillar.
     116        }
     117
     118        public function test_suggestions_with_type_members_and_term_as_displayname() {
     119                $suggestions = bp_core_get_suggestions( array(
     120                        'type' => 'members',
     121                        'term' => 'aardvark',
     122                ) );
     123
     124                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
     125        }
     126
     127        public function test_suggestions_with_type_members_and_term_as_usernicename() {
     128                $suggestions = bp_core_get_suggestions( array(
     129                        'type' => 'members',
     130                        'term' => 'eleanor',
     131                ) );
     132
     133                $this->assertEquals( 1, count( $suggestions ) );  // snake.
     134        }
     135
     136        public function test_suggestions_with_term_as_current_user() {
     137                $suggestions = bp_core_get_suggestions( array(
     138                        'type' => 'members',
     139                        'term' => 'katie',
     140                ) );
     141                $this->assertEquals( 1, count( $suggestions ) );
     142                $this->assertSame( 'admin', $suggestions[0]->id );
     143        }
     144
     145
     146        public function test_suggestions_with_type_groupmembers_public() {
     147                $suggestions = bp_core_get_suggestions( array(
     148                        'object_id' => $this->group_ids['public'],
     149                        'type'      => 'group-members',
     150                        'term'      => 'smith',
     151                ) );
     152
     153                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
     154        }
     155
     156        public function test_suggestions_with_type_groupmembers_public_and_limit() {
     157                $suggestions = bp_core_get_suggestions( array(
     158                        'limit'     => 1,
     159                        'object_id' => $this->group_ids['public'],
     160                        'type'      => 'group-members',
     161                        'term'      => 'smith',
     162                ) );
     163
     164                $this->assertEquals( 1, count( $suggestions ) );  // one of: aardvark, smith.
     165        }
     166
     167        public function test_suggestions_with_type_groupmembers_public_and_only_friends() {
     168                $suggestions = bp_core_get_suggestions( array(
     169                        'object_id'    => $this->group_ids['public'],
     170                        'only_friends' => true,
     171                        'type'         => 'group-members',
     172                        'term'         => 'smith',
     173                ) );
     174
     175                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
     176        }
     177
     178        public function test_suggestions_with_type_groupmembers_public_and_term_as_displayname() {
     179                $suggestions = bp_core_get_suggestions( array(
     180                        'object_id' => $this->group_ids['public'],
     181                        'type'      => 'group-members',
     182                        'term'      => 'aardvark',
     183                ) );
     184
     185                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
     186        }
     187
     188        public function test_suggestions_with_type_groupmembers_public_and_term_as_usernicename() {
     189                $suggestions = bp_core_get_suggestions( array(
     190                        'object_id' => $this->group_ids['public'],
     191                        'type'      => 'group-members',
     192                        'term'      => 'robert',
     193                ) );
     194
     195                $this->assertEquals( 1, count( $suggestions ) );  // smith.
     196        }
     197
     198        public function test_suggestions_with_type_groupmembers_public_as_id() {
     199                $suggestions = bp_core_get_suggestions( array(
     200                        'object_id' => $this->group_ids['public'],
     201                        'type'      => 'group-members',
     202                        'term'      => 'smith',
     203                ) );
     204
     205                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
     206        }
     207
     208        public function test_suggestions_with_type_groupmembers_public_as_slug() {
     209                $suggestions = bp_core_get_suggestions( array(
     210                        'object_id' => $this->group_slugs['public'],
     211                        'type'      => 'group-members',
     212                        'term'      => 'smith',
     213                ) );
     214
     215                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
     216        }
     217
     218        public function test_suggestions_with_type_groupmembers_hidden() {
     219                // current_user isn't a member of the hidden group
     220                $suggestions = bp_core_get_suggestions( array(
     221                        'object_id' => $this->group_ids['hidden'],
     222                        'type'      => 'group-members',
     223                        'term'      => 'pig',
     224                ) );
     225                $this->assertTrue( is_wp_error( $suggestions ) );
     226
     227                // "alpaca red" is in the hidden group
     228                $this->set_current_user( $this->users['alpaca red'] );
     229                $suggestions = bp_core_get_suggestions( array(
     230                        'object_id' => $this->group_ids['hidden'],
     231                        'type'      => 'group-members',
     232                        'term'      => 'pig',
     233                ) );
     234                $this->assertEquals( 1, count( $suggestions ) );  // pig
     235        }
     236
     237        public function test_suggestions_with_type_groupmembers_private() {
     238                // current_user isn't a member of the private group
     239                $suggestions = bp_core_get_suggestions( array(
     240                        'object_id' => $this->group_ids['private'],
     241                        'type'      => 'group-members',
     242                        'term'      => 'cat',
     243                ) );
     244                $this->assertTrue( is_wp_error( $suggestions ) );
     245
     246                // "caterpillar" is in the private group
     247                $this->set_current_user( $this->users['caterpillar'] );
     248                $suggestions = bp_core_get_suggestions( array(
     249                        'object_id' => $this->group_ids['private'],
     250                        'type'      => 'group-members',
     251                        'term'      => 'cat',
     252                ) );
     253                $this->assertEquals( 2, count( $suggestions ) );  // cat, caterpillar
     254        }
     255
     256
     257        /**
     258         * These next tests check the format of the response from the Suggestions API.
     259         */
     260
     261        public function test_suggestions_response_no_matches() {
     262                $suggestions = bp_core_get_suggestions( array(
     263                        'term' => 'abcdefghijklmnopqrstuvwxyz',
     264                ) );
     265
     266                $this->assertInternalType( 'array', $suggestions );
     267                $this->assertEmpty( $suggestions );
     268        }
     269
     270        public function test_suggestions_response_single_match() {
     271                $suggestion = bp_core_get_suggestions( array(
     272                        'term' => 'zoom',
     273                ) );
     274
     275                $this->assertInternalType( 'array', $suggestion );
     276                $this->assertNotEmpty( $suggestion );
     277
     278                $suggestion = array_shift( $suggestion );
     279
     280                $this->assertInternalType( 'object', $suggestion );
     281                $this->assertAttributeNotEmpty( 'image', $suggestion );
     282                $this->assertAttributeNotEmpty( 'id', $suggestion );
     283                $this->assertAttributeNotEmpty( 'name', $suggestion );
     284        }
     285
     286        public function test_suggestions_response_multiple_matches() {
     287                $suggestions = bp_core_get_suggestions( array(
     288                        'term' => 'cat',
     289                ) );
     290
     291                $this->assertInternalType( 'array', $suggestions );
     292                $this->assertNotEmpty( $suggestions );
     293
     294                foreach ( $suggestions as $suggestion ) {
     295                        $this->assertInternalType( 'object', $suggestion );
     296                        $this->assertAttributeNotEmpty( 'image', $suggestion );
     297                        $this->assertAttributeNotEmpty( 'id', $suggestion );
     298                        $this->assertAttributeNotEmpty( 'name', $suggestion );
     299                }
     300        }
     301
     302        public function test_suggestions_term_is_case_insensitive() {
     303                $lowercase = bp_core_get_suggestions( array(
     304                        'term' => 'lisa',
     305                ) );
     306                $this->assertEquals( 1, count( $lowercase ) );
     307
     308                $uppercase = bp_core_get_suggestions( array(
     309                        'term' => 'LISA',
     310                ) );
     311                $this->assertEquals( 1, count( $uppercase ) );
     312
     313                $this->assertSame( $lowercase[0]->id, $uppercase[0]->id );
     314                $this->assertSame( 'zoom', $lowercase[0]->id );
     315        }
     316
     317        public function test_suggestions_response_property_types() {
     318                $suggestion = bp_core_get_suggestions( array(
     319                        'term' => 'zoom',
     320                ) );
     321
     322                $this->assertInternalType( 'array', $suggestion );
     323                $this->assertNotEmpty( $suggestion );
     324
     325                $suggestion = array_shift( $suggestion );
     326
     327                $this->assertInternalType( 'object', $suggestion );
     328                $this->assertAttributeInternalType( 'string', 'image', $suggestion );
     329                $this->assertAttributeInternalType( 'string', 'id', $suggestion );
     330                $this->assertAttributeInternalType( 'string', 'name', $suggestion );
     331        }
     332
     333
     334        /**
     335         * Tests below this point are expected to fail.
     336         */
     337
     338        public function test_suggestions_with_bad_type() {
     339                $suggestions = bp_core_get_suggestions( array(
     340                        'type' => 'fake_type',
     341                ) );
     342
     343                $this->assertTrue( is_wp_error( $suggestions ) );
     344        }
     345
     346        public function test_suggestions_with_type_groupmembers_and_bad_object_id() {
     347                // object_id must be a positive integer.
     348                $suggestions = bp_core_get_suggestions( array(
     349                        'object_id' => -12,
     350                        'type'      => 'group-members',
     351                ) );
     352                $this->assertTrue( is_wp_error( $suggestions ) );
     353
     354                // object_id can also be a group slug.
     355                $suggestions = bp_core_get_suggestions( array(
     356                        'object_id' => 'fake-group-slug',
     357                        'type'      => 'group-members',
     358                ) );
     359                $this->assertTrue( is_wp_error( $suggestions ) );
     360
     361                // object_id must be set when scope=group
     362                $suggestions = bp_core_get_suggestions( array(
     363                        'type' => 'group-members',
     364                ) );
     365                $this->assertTrue( is_wp_error( $suggestions ) );
     366        }
     367
     368        public function test_suggestions_with_type_members_and_object_id() {
     369                // object_id cannot be set when scope=global
     370                $suggestions = bp_core_get_suggestions( array(
     371                        'object_id' => 12,
     372                        'type'      => 'members',
     373                ) );
     374
     375                $this->assertTrue( is_wp_error( $suggestions ) );
     376        }
     377
     378        public function test_suggestions_with_bad_term() {
     379                // a non-empty term is mandatory
     380                $suggestions = bp_core_get_suggestions( array(
     381                        'term' => '',
     382                ) );
     383
     384                $this->assertTrue( is_wp_error( $suggestions ) );
     385        }
     386}
     387 No newline at end of file
  • src/bp-members/bp-members-functions.php

    -- 
    1.9.3
    
    
    From adb7f2705e15a288c79e51c42b28a035a83ec94b Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 14:00:10 +0100
    Subject: [PATCH 02/35] Suggestions: sanitise only_friends param
    
    ---
     src/bp-members/bp-members-functions.php | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 6e28ec3..9f8a498 100644
    a b function bp_members_get_suggestions( $args ) { 
    21072107                'only_friends' => false,
    21082108                'term'         => '',     // Sanitised upstream
    21092109        );
    2110         $args = apply_filters( 'bp_members_get_suggestions_args', wp_parse_args( $args, $defaults ) );
    21112110
    21122111        if ( $args['only_friends'] && ! bp_is_active( 'friends' ) ) {
    21132112                // Friends component is missing.
  • src/bp-members/bp-members-functions.php

    -- 
    1.9.3
    
    
    From 30569b070333aee5d2e8c870a5e033c758d3bc64 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 14:00:38 +0100
    Subject: [PATCH 03/35] Suggestions: sanitise only_friends param
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    (Let’s try to commit the whole thing this time)
    ---
     src/bp-members/bp-members-functions.php | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 9f8a498..bccedc1 100644
    a b function bp_members_get_suggestions( $args ) { 
    21072107                'only_friends' => false,
    21082108                'term'         => '',     // Sanitised upstream
    21092109        );
     2110        $args                 = apply_filters( 'bp_members_get_suggestions_args', wp_parse_args( $args, $defaults ) );
     2111        $args['only_friends'] = (bool) $args['only_friends'];
     2112
    21102113
    21112114        if ( $args['only_friends'] && ! bp_is_active( 'friends' ) ) {
    21122115                // Friends component is missing.
  • src/bp-members/bp-members-filters.php

    -- 
    1.9.3
    
    
    From 760fa37bef55193ca38b387741c66f73df364c52 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 14:51:50 +0100
    Subject: [PATCH 04/35] phpDoc tweaks
    
    ---
     src/bp-members/bp-members-filters.php   | 2 +-
     src/bp-members/bp-members-functions.php | 3 ++-
     2 files changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/src/bp-members/bp-members-filters.php b/src/bp-members/bp-members-filters.php
    index 3c0c610..8860609 100644
    a b function bp_members_register_suggestion_types( $types ) { 
    8989        $types['members'] = 'bp_members_get_suggestions';
    9090        return $types;
    9191}
    92 add_filter( 'bp_suggestions_get_types', 'bp_members_register_suggestion_types' );
     92add_filter( 'bp_suggestions_get_types', 'bp_members_register_suggestion_types' );
     93 No newline at end of file
  • src/bp-members/bp-members-functions.php

    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index bccedc1..63b6465 100644
    a b function bp_live_spammer_login_error() { 
    20932093 * by this particular Suggestions API extension.
    20942094 *
    20952095 * @param array $args {
    2096  *     @type int limit Maximum number of results to display. Default: 16.
     2096 *     @type int $limit Maximum number of results to display. Default: 16.
     2097 *     @type bool $only_friends If true, only return matches who are friends with the current user. Default: false.
    20972098 *     @type string $term The suggestion service will try to find results that contain this string.
    20982099 *           Mandatory.
    20992100 * }
  • src/bp-friends/bp-friends-filters.php

    -- 
    1.9.3
    
    
    From a9e1785ca59cde277377ce6751a91d27841e5002 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 15:45:21 +0100
    Subject: [PATCH 05/35] Suggestions: move user friends logic into Friends
     component
    
    ---
     src/bp-friends/bp-friends-filters.php   |  2 ++
     src/bp-friends/bp-friends-functions.php | 20 ++++++++++++++++++++
     src/bp-members/bp-members-functions.php | 11 +++--------
     3 files changed, 25 insertions(+), 8 deletions(-)
    
    diff --git a/src/bp-friends/bp-friends-filters.php b/src/bp-friends/bp-friends-filters.php
    index 6ada0e7..69b39dd 100644
    a b function bp_friends_filter_user_query_populate_extras( BP_User_Query $user_query 
    5050        }
    5151}
    5252add_filter( 'bp_user_query_populate_extras', 'bp_friends_filter_user_query_populate_extras', 4, 2 );
     53
     54add_filter( 'bp_suggestions_members_query_args', 'bp_friends_suggestions_filter_query_args', 10, 2 );
     55 No newline at end of file
  • src/bp-friends/bp-friends-functions.php

    diff --git a/src/bp-friends/bp-friends-functions.php b/src/bp-friends/bp-friends-functions.php
    index 5f797c7..dce5320 100644
    a b function friends_remove_data( $user_id ) { 
    566566add_action( 'wpmu_delete_user',  'friends_remove_data' );
    567567add_action( 'delete_user',       'friends_remove_data' );
    568568add_action( 'bp_make_spam_user', 'friends_remove_data' );
     569
     570/**
     571 * Extend the members' component's @username suggestions by adding support for friendships.
     572 *
     573 * Assumes there is currently a logged-in user.
     574 *
     575 * @param array $query_args The parameters that will be passed to {@see BP_User_Query}.
     576 * @param array $suggestion_args Arguments originally sent to the {@see bp_core_get_suggestions()}.
     577 * @return array The parameters that will be passed to {@see BP_User_Query}.
     578 * @see bp_members_get_suggestions()
     579 * @since BuddyPress (2.1.0)
     580 */
     581function bp_friends_suggestions_filter_query_args( $query_args, $suggestion_args ) {
     582        if ( $suggestion_args['only_friends'] ) {
     583                // Only return matches of friends of this user.
     584                $query_args['user_id'] = get_current_user_id();
     585        }
     586
     587        return $query_args;
     588}
     589 No newline at end of file
  • src/bp-members/bp-members-functions.php

    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 63b6465..d182256 100644
    a b function bp_live_spammer_login_error() { 
    20942094 *
    20952095 * @param array $args {
    20962096 *     @type int $limit Maximum number of results to display. Default: 16.
    2097  *     @type bool $only_friends If true, only return matches who are friends with the current user. Default: false.
     2097 *     @type bool $only_friends If true, only match the current user's friends. Default: false.
    20982098 *     @type string $term The suggestion service will try to find results that contain this string.
    20992099 *           Mandatory.
    21002100 * }
    function bp_members_get_suggestions( $args ) { 
    21122112        $args['only_friends'] = (bool) $args['only_friends'];
    21132113
    21142114
    2115         if ( $args['only_friends'] && ! bp_is_active( 'friends' ) ) {
     2115        if ( $args['only_friends'] && ( ! bp_is_active( 'friends' ) || ! is_user_logged_in() ) ) {
    21162116                // Friends component is missing.
    21172117                return new WP_Error( 'missing_requirement' );
    21182118        }
    function bp_members_get_suggestions( $args ) { 
    21272127                'search_terms'    => $args['term'],
    21282128        );
    21292129
    2130         if ( $args['only_friends'] ) {
    2131                 $user_query['user_id'] = get_current_user_id();
    2132         }
    2133 
    2134 
    2135         $user_query = new BP_User_Query( $user_query );
     2130        $user_query = new BP_User_Query( apply_filters( 'bp_suggestions_members_query_args', $user_query, $args ) );
    21362131        $results    = array();
    21372132
    21382133        foreach ( $user_query->results as $user ) {
  • src/bp-core/bp-core-functions.php

    -- 
    1.9.3
    
    
    From 3ceb230e58d8c688eeea73376cd1b7664b351a71 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 15:47:19 +0100
    Subject: [PATCH 06/35] Suggestions: remove object_id logic for now.
    
    Re-implementing/renaming/re-working.
    ---
     src/bp-core/bp-core-functions.php     | 10 ------
     src/bp-groups/bp-groups-filters.php   | 13 +++++++
     src/bp-groups/bp-groups-functions.php | 66 +++++++++++++++++++++++++++++++++++
     3 files changed, 79 insertions(+), 10 deletions(-)
    
    diff --git a/src/bp-core/bp-core-functions.php b/src/bp-core/bp-core-functions.php
    index 75cb9f5..837113a 100644
    a b function bp_nav_menu_get_item_url( $slug ) { 
    19431943 *
    19441944 * @param array $args {
    19451945 *     @type int limit Maximum number of results to display. Default: 16.
    1946  *     @type int|string $object_id Specifies a particular object that may be used by a suggestion
    1947  *           service. Accepts either an integer or a string. For example, this could be used by a
    1948  *           Groups suggestion type that searches for members who are members of a specific group.
    19491946 *     @type string $type The name of the suggestion service to use for the request. Mandatory.
    19501947 *     @type string $term The suggestion service will try to find results that contain this string.
    19511948 *           Mandatory.
    function bp_nav_menu_get_item_url( $slug ) { 
    19561953function bp_core_get_suggestions( $args ) {
    19571954        $defaults = array(
    19581955                'limit'     => 16,
    1959                 'object_id' => 0,
    19601956                'type'      => '',
    19611957                'term'      => '',
    19621958        );
    19631959        $args = wp_parse_args( $args, $defaults );
    19641960
    1965         if ( ctype_digit( $args['object_id'] ) ) {
    1966                 $args['object_id'] = absint( $args['object_id'] );
    1967         } else {
    1968                 $args['object_id'] = sanitize_text_field( $args['object_id'] );
    1969         }
    1970 
    19711961        $args['limit'] = absint( $args['limit'] );
    19721962        $args['term']  = trim( sanitize_text_field( $args['term'] ) );
    19731963
  • src/bp-groups/bp-groups-filters.php

    diff --git a/src/bp-groups/bp-groups-filters.php b/src/bp-groups/bp-groups-filters.php
    index 5ec2d91..8df573e 100644
    a b function groups_filter_forums_root_page_sql( $sql ) { 
    205205        return apply_filters( 'groups_filter_bbpress_root_page_sql', 't.topic_id' );
    206206}
    207207add_filter( 'get_latest_topics_fields', 'groups_filter_forums_root_page_sql' );
     208
     209/**
     210 * Add support for @username mentions for people who belong to a specific Group.
     211 *
     212 * @param array $types Array of registered extensions to the Suggestion API.
     213 * @return array
     214 * @see bp_core_get_suggestions()
     215 */
     216function bp_groups_register_suggestion_types( $types ) {
     217        $types['group-members'] = 'bp_groups_get_member_suggestions';
     218        return $types;
     219}
     220add_filter( 'bp_suggestions_get_types', 'bp_groups_register_suggestion_types' );
     221 No newline at end of file
  • src/bp-groups/bp-groups-functions.php

    diff --git a/src/bp-groups/bp-groups-functions.php b/src/bp-groups/bp-groups-functions.php
    index 971f8b1..d3cdfdd 100644
    a b function groups_remove_data_for_user( $user_id ) { 
    11531153add_action( 'wpmu_delete_user',  'groups_remove_data_for_user' );
    11541154add_action( 'delete_user',       'groups_remove_data_for_user' );
    11551155add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
     1156
     1157
     1158/**
     1159 * Implement support for @username mentions for people who belong to a specific Group.
     1160 *
     1161 * The $args parameter may include other parameters not documented here; if so, they are not used
     1162 * by this particular Suggestions API extension.
     1163 *
     1164 * @param array $args {
     1165 *     @type int $limit Maximum number of results to display. Default: 16.
     1166 *     @type bool $only_friends If true, only return matches who are friends with the current user. Default: false.
     1167 *     @type string $term The suggestion service will try to find results that contain this string.
     1168 *           Mandatory.
     1169 * }
     1170 * @return array|WP_Error See {@see bp_core_get_suggestions()}. If any problems, return a WP_Error.
     1171 * @see bp_core_get_suggestions()
     1172 * @since BuddyPress (2.1.0)
     1173 */
     1174function bp_groups_get_member_suggestions( $args ) {
     1175        $defaults = array(
     1176                'limit'        => 16,     // Sanitised upstream
     1177                'only_friends' => false,
     1178                'term'         => '',     // Sanitised upstream
     1179        );
     1180        $args                 = apply_filters( 'bp_groups_get_member_suggestions_args', wp_parse_args( $args, $defaults ) );
     1181        $args['only_friends'] = (bool) $args['only_friends'];
     1182
     1183
     1184        if ( $args['only_friends'] && ! bp_is_active( 'friends' ) ) {
     1185                // Friends component is missing.
     1186                return new WP_Error( 'missing_requirement' );
     1187        }
     1188
     1189        $user_query = array(
     1190                'count_total'     => '',  // Prevents total count
     1191                'populate_extras' => false,
     1192                'type'            => 'alphabetical',
     1193
     1194                'page'            => 1,
     1195                'per_page'        => $args['limit'],
     1196                'search_terms'    => $args['term'],
     1197        );
     1198
     1199        if ( $args['only_friends'] ) {
     1200                $user_query['user_id'] = get_current_user_id();
     1201        }
     1202
     1203
     1204        $user_query = new BP_User_Query( $user_query );
     1205        $results    = array();
     1206
     1207        foreach ( $user_query->results as $user ) {
     1208                $result        = new stdClass();
     1209                $result->ID    = $user->user_nicename;
     1210                $result->image = get_avatar( $user );
     1211                $result->name  = $user->display_name;
     1212
     1213                if ( bp_disable_profile_sync() ) {
     1214                        $result->name = BP_XProfile_Field::get_fullname( $user->ID );
     1215                }
     1216
     1217                $results[] = $result;
     1218        }
     1219
     1220        return apply_filters( 'bp_groups_get_member_suggestions', $results, $args );
     1221}
     1222 No newline at end of file
  • src/bp-groups/bp-groups-functions.php

    -- 
    1.9.3
    
    
    From e164fbc0aa1bb7b5ff21706383e806dc95108fa9 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 16:10:23 +0100
    Subject: [PATCH 07/35] Removing code that shouldn't been committed yet.
    
    ---
     src/bp-groups/bp-groups-functions.php | 65 -----------------------------------
     1 file changed, 65 deletions(-)
    
    diff --git a/src/bp-groups/bp-groups-functions.php b/src/bp-groups/bp-groups-functions.php
    index d3cdfdd..a8cbab9 100644
    a b function groups_remove_data_for_user( $user_id ) { 
    11541154add_action( 'delete_user',       'groups_remove_data_for_user' );
    11551155add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
    11561156
    1157 
    1158 /**
    1159  * Implement support for @username mentions for people who belong to a specific Group.
    1160  *
    1161  * The $args parameter may include other parameters not documented here; if so, they are not used
    1162  * by this particular Suggestions API extension.
    1163  *
    1164  * @param array $args {
    1165  *     @type int $limit Maximum number of results to display. Default: 16.
    1166  *     @type bool $only_friends If true, only return matches who are friends with the current user. Default: false.
    1167  *     @type string $term The suggestion service will try to find results that contain this string.
    1168  *           Mandatory.
    1169  * }
    1170  * @return array|WP_Error See {@see bp_core_get_suggestions()}. If any problems, return a WP_Error.
    1171  * @see bp_core_get_suggestions()
    1172  * @since BuddyPress (2.1.0)
    1173  */
    1174 function bp_groups_get_member_suggestions( $args ) {
    1175         $defaults = array(
    1176                 'limit'        => 16,     // Sanitised upstream
    1177                 'only_friends' => false,
    1178                 'term'         => '',     // Sanitised upstream
    1179         );
    1180         $args                 = apply_filters( 'bp_groups_get_member_suggestions_args', wp_parse_args( $args, $defaults ) );
    1181         $args['only_friends'] = (bool) $args['only_friends'];
    1182 
    1183 
    1184         if ( $args['only_friends'] && ! bp_is_active( 'friends' ) ) {
    1185                 // Friends component is missing.
    1186                 return new WP_Error( 'missing_requirement' );
    1187         }
    1188 
    1189         $user_query = array(
    1190                 'count_total'     => '',  // Prevents total count
    1191                 'populate_extras' => false,
    1192                 'type'            => 'alphabetical',
    1193 
    1194                 'page'            => 1,
    1195                 'per_page'        => $args['limit'],
    1196                 'search_terms'    => $args['term'],
    1197         );
    1198 
    1199         if ( $args['only_friends'] ) {
    1200                 $user_query['user_id'] = get_current_user_id();
    1201         }
    1202 
    1203 
    1204         $user_query = new BP_User_Query( $user_query );
    1205         $results    = array();
    1206 
    1207         foreach ( $user_query->results as $user ) {
    1208                 $result        = new stdClass();
    1209                 $result->ID    = $user->user_nicename;
    1210                 $result->image = get_avatar( $user );
    1211                 $result->name  = $user->display_name;
    1212 
    1213                 if ( bp_disable_profile_sync() ) {
    1214                         $result->name = BP_XProfile_Field::get_fullname( $user->ID );
    1215                 }
    1216 
    1217                 $results[] = $result;
    1218         }
    1219 
    1220         return apply_filters( 'bp_groups_get_member_suggestions', $results, $args );
    1221 }
    1222  No newline at end of file
  • src/bp-members/bp-members-functions.php

    -- 
    1.9.3
    
    
    From 74d23221b179788b566ae55d9ffbb2b142d0dd11 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 17:03:00 +0100
    Subject: [PATCH 08/35] Allow components to bail out of suggestions if the
     request is bad
    
    ---
     src/bp-members/bp-members-functions.php | 11 +++++++++--
     1 file changed, 9 insertions(+), 2 deletions(-)
    
    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index d182256..2fbcd17 100644
    a b function bp_members_get_suggestions( $args ) { 
    21182118        }
    21192119
    21202120        $user_query = array(
     2121        $user_query = apply_filters( 'bp_suggestions_members_query_args', array(
    21212122                'count_total'     => '',  // Prevents total count
    21222123                'populate_extras' => false,
    21232124                'type'            => 'alphabetical',
    function bp_members_get_suggestions( $args ) { 
    21252126                'page'            => 1,
    21262127                'per_page'        => $args['limit'],
    21272128                'search_terms'    => $args['term'],
    2128         );
     2129        ), $args );
     2130
     2131        // Allow components to bail us out if the request is bad.
     2132        if ( is_wp_error( $user_query ) ) {
     2133                return $user_query;
     2134        }
     2135
    21292136
    2130         $user_query = new BP_User_Query( apply_filters( 'bp_suggestions_members_query_args', $user_query, $args ) );
     2137        $user_query = new BP_User_Query( $user_query );
    21312138        $results    = array();
    21322139
    21332140        foreach ( $user_query->results as $user ) {
  • src/bp-friends/bp-friends-functions.php

    -- 
    1.9.3
    
    
    From 6bd552b446ac2d8879c1cacb4854a6deeb2e4bef Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 17:03:54 +0100
    Subject: [PATCH 09/35] Suggestions, Members: support filtering by group.
    
    ---
     src/bp-friends/bp-friends-functions.php |  2 +-
     src/bp-groups/bp-groups-filters.php     | 13 +---------
     src/bp-groups/bp-groups-functions.php   | 42 +++++++++++++++++++++++++++++++++
     src/bp-members/bp-members-functions.php |  9 ++++++-
     4 files changed, 52 insertions(+), 14 deletions(-)
    
    diff --git a/src/bp-friends/bp-friends-functions.php b/src/bp-friends/bp-friends-functions.php
    index dce5320..fa7ff37 100644
    a b function friends_remove_data( $user_id ) { 
    574574 *
    575575 * @param array $query_args The parameters that will be passed to {@see BP_User_Query}.
    576576 * @param array $suggestion_args Arguments originally sent to the {@see bp_core_get_suggestions()}.
    577  * @return array The parameters that will be passed to {@see BP_User_Query}.
     577 * @return array|WP_Error The parameters that will be passed to {@see BP_User_Query}.
    578578 * @see bp_members_get_suggestions()
    579579 * @since BuddyPress (2.1.0)
    580580 */
  • src/bp-groups/bp-groups-filters.php

    diff --git a/src/bp-groups/bp-groups-filters.php b/src/bp-groups/bp-groups-filters.php
    index 8df573e..77cbf27 100644
    a b function groups_filter_forums_root_page_sql( $sql ) { 
    206206}
    207207add_filter( 'get_latest_topics_fields', 'groups_filter_forums_root_page_sql' );
    208208
    209 /**
    210  * Add support for @username mentions for people who belong to a specific Group.
    211  *
    212  * @param array $types Array of registered extensions to the Suggestion API.
    213  * @return array
    214  * @see bp_core_get_suggestions()
    215  */
    216 function bp_groups_register_suggestion_types( $types ) {
    217         $types['group-members'] = 'bp_groups_get_member_suggestions';
    218         return $types;
    219 }
    220 add_filter( 'bp_suggestions_get_types', 'bp_groups_register_suggestion_types' );
    221  No newline at end of file
     209add_filter( 'bp_suggestions_members_query_args', 'bp_groups_suggestions_filter_query_args', 10, 2 );
     210 No newline at end of file
  • src/bp-groups/bp-groups-functions.php

    diff --git a/src/bp-groups/bp-groups-functions.php b/src/bp-groups/bp-groups-functions.php
    index a8cbab9..a1b27df 100644
    a b function groups_remove_data_for_user( $user_id ) { 
    11541154add_action( 'delete_user',       'groups_remove_data_for_user' );
    11551155add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
    11561156
     1157/*** Suggestions API ************************************************************/
     1158
     1159/**
     1160 * Extend the members' component's @username suggestions by adding support for group memberships.
     1161 *
     1162 * @param array $query_args The parameters that will be passed to {@see BP_User_Query}.
     1163 * @param array $suggestion_args Arguments originally sent to the {@see bp_core_get_suggestions()}.
     1164 * @return array|WP_Error The parameters that will be passed to {@see BP_User_Query}.
     1165 * @see bp_members_get_suggestions()
     1166 * @since BuddyPress (2.1.0)
     1167 */
     1168function bp_groups_suggestions_filter_query_args( $query_args, $suggestion_args ) {
     1169        if ( ! $suggestion_args['group_id'] ) {
     1170                return $query_args;
     1171        }
     1172
     1173        $the_group = groups_get_group( array(
     1174                'group_id'        => $suggestion_args['group_id'],
     1175                'populate_extras' => true,
     1176        ) );
     1177
     1178        if ( $the_group->id === 0 || ! $the_group->user_has_access ) {
     1179                return new WP_Error( 'access_denied' );
     1180        }
     1181
     1182        $group_query = array(
     1183                'count_total'     => '',  // Prevents total count
     1184                'populate_extras' => false,
     1185                'type'            => 'alphabetical',
     1186
     1187                'group_id'        => $suggestion_args['group_id'],
     1188        );
     1189
     1190        $group_users = new BP_Group_Member_Query( $group_query );
     1191        if ( $group_users->results ) {
     1192                $query_args['include'] = wp_list_pluck( $group_users->results, 'ID' );
     1193        } else {
     1194                $query_args['include'] = array( 0 );
     1195        }
     1196
     1197        return $query_args;
     1198}
     1199 No newline at end of file
  • src/bp-members/bp-members-functions.php

    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 2fbcd17..24f5ddb 100644
    a b function bp_live_spammer_login_error() { 
    20932093 * by this particular Suggestions API extension.
    20942094 *
    20952095 * @param array $args {
     2096 *     @type int $group_id If set, only match users that are in this group.
    20962097 *     @type int $limit Maximum number of results to display. Default: 16.
    20972098 *     @type bool $only_friends If true, only match the current user's friends. Default: false.
    20982099 *     @type string $term The suggestion service will try to find results that contain this string.
    function bp_live_spammer_login_error() { 
    21042105 */
    21052106function bp_members_get_suggestions( $args ) {
    21062107        $defaults = array(
     2108                'group_id'     => 0,
    21072109                'limit'        => 16,     // Sanitised upstream
    21082110                'only_friends' => false,
    21092111                'term'         => '',     // Sanitised upstream
    21102112        );
    21112113        $args                 = apply_filters( 'bp_members_get_suggestions_args', wp_parse_args( $args, $defaults ) );
     2114        $args['group_id']     = absint( $args['group_id'] );
    21122115        $args['only_friends'] = (bool) $args['only_friends'];
    21132116
    21142117
    function bp_members_get_suggestions( $args ) { 
    21172120                return new WP_Error( 'missing_requirement' );
    21182121        }
    21192122
    2120         $user_query = array(
     2123        if ( $args['group_id'] && ! bp_is_active( 'groups' ) ) {
     2124                // Groups component is missing.
     2125                return new WP_Error( 'missing_requirement' );
     2126        }
     2127
    21212128        $user_query = apply_filters( 'bp_suggestions_members_query_args', array(
    21222129                'count_total'     => '',  // Prevents total count
    21232130                'populate_extras' => false,
  • tests/phpunit/testcases/apis/suggestions-nonauth.php

    -- 
    1.9.3
    
    
    From 6f32be7a364d78fcf09e813faffc88a75bfbbb91 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 17:04:19 +0100
    Subject: [PATCH 10/35] Update tests for recent API changes.
    
    ---
     .../phpunit/testcases/apis/suggestions-nonauth.php | 18 ++--
     tests/phpunit/testcases/apis/suggestions.php       | 96 +++++++++-------------
     2 files changed, 49 insertions(+), 65 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    index 0e1be23..0c67d17 100644
    a b public function test_suggestions_with_type_members_and_only_friends() { 
    7373                $this->assertTrue( is_wp_error( $suggestions ) );
    7474        }
    7575
    76         public function test_suggestions_with_type_group_and_only_friends() {
     76        public function test_suggestions_with_type_groupmembers_and_only_friends() {
    7777                // only_friends requires authenticated requests
    7878                $suggestions = bp_core_get_suggestions( array(
    79                         'object_id'    => $this->group_ids['public'],
     79                        'group_id'     => $this->group_ids['public'],
    8080                        'only_friends' => true,
    81                         'type'         => 'group-members',
     81                        'type'         => 'members',
    8282                        'term'         => 'smith',
    8383                ) );
    8484
    8585                $this->assertTrue( is_wp_error( $suggestions ) );
    8686        }
    8787
    88         public function test_suggestions_with_type_group_hidden() {
     88        public function test_suggestions_with_type_groupmembers_hidden() {
    8989                $suggestions = bp_core_get_suggestions( array(
    90                         'object_id' => $this->group_ids['hidden'],
    91                         'type'      => 'group-members',
     90                        'group_id' => $this->group_ids['hidden'],
     91                        'type'      => 'members',
    9292                        'term'      => 'pig',
    9393                ) );
    9494
    9595                $this->assertTrue( is_wp_error( $suggestions ) );
    9696        }
    9797
    98         public function test_suggestions_with_type_group_private() {
     98        public function test_suggestions_with_type_groupmembers_private() {
    9999                $suggestions = bp_core_get_suggestions( array(
    100                         'object_id' => $this->group_ids['private'],
    101                         'type'      => 'group-members',
     100                        'group_id' => $this->group_ids['private'],
     101                        'type'      => 'members',
    102102                        'term'      => 'cat',
    103103                ) );
    104104
  • tests/phpunit/testcases/apis/suggestions.php

    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 7fc85d7..b2d6274 100644
    a b public function test_suggestions_with_term_as_current_user() { 
    145145
    146146        public function test_suggestions_with_type_groupmembers_public() {
    147147                $suggestions = bp_core_get_suggestions( array(
    148                         'object_id' => $this->group_ids['public'],
    149                         'type'      => 'group-members',
    150                         'term'      => 'smith',
     148                        'group_id' => $this->group_ids['public'],
     149                        'type'     => 'members',
     150                        'term'     => 'smith',
    151151                ) );
    152152
    153153                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    public function test_suggestions_with_type_groupmembers_public() { 
    155155
    156156        public function test_suggestions_with_type_groupmembers_public_and_limit() {
    157157                $suggestions = bp_core_get_suggestions( array(
    158                         'limit'     => 1,
    159                         'object_id' => $this->group_ids['public'],
    160                         'type'      => 'group-members',
    161                         'term'      => 'smith',
     158                        'limit'    => 1,
     159                        'group_id' => $this->group_ids['public'],
     160                        'type'     => 'members',
     161                        'term'     => 'smith',
    162162                ) );
    163163
    164164                $this->assertEquals( 1, count( $suggestions ) );  // one of: aardvark, smith.
    public function test_suggestions_with_type_groupmembers_public_and_limit() { 
    166166
    167167        public function test_suggestions_with_type_groupmembers_public_and_only_friends() {
    168168                $suggestions = bp_core_get_suggestions( array(
    169                         'object_id'    => $this->group_ids['public'],
     169                        'group_id'     => $this->group_ids['public'],
    170170                        'only_friends' => true,
    171                         'type'         => 'group-members',
     171                        'type'         => 'members',
    172172                        'term'         => 'smith',
    173173                ) );
    174174
    public function test_suggestions_with_type_groupmembers_public_and_only_friends( 
    177177
    178178        public function test_suggestions_with_type_groupmembers_public_and_term_as_displayname() {
    179179                $suggestions = bp_core_get_suggestions( array(
    180                         'object_id' => $this->group_ids['public'],
    181                         'type'      => 'group-members',
    182                         'term'      => 'aardvark',
     180                        'group_id' => $this->group_ids['public'],
     181                        'type'     => 'members',
     182                        'term'     => 'aardvark',
    183183                ) );
    184184
    185185                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
    public function test_suggestions_with_type_groupmembers_public_and_term_as_displ 
    187187
    188188        public function test_suggestions_with_type_groupmembers_public_and_term_as_usernicename() {
    189189                $suggestions = bp_core_get_suggestions( array(
    190                         'object_id' => $this->group_ids['public'],
    191                         'type'      => 'group-members',
    192                         'term'      => 'robert',
     190                        'group_id' => $this->group_ids['public'],
     191                        'type'     => 'members',
     192                        'term'     => 'robert',
    193193                ) );
    194194
    195195                $this->assertEquals( 1, count( $suggestions ) );  // smith.
    public function test_suggestions_with_type_groupmembers_public_and_term_as_usern 
    197197
    198198        public function test_suggestions_with_type_groupmembers_public_as_id() {
    199199                $suggestions = bp_core_get_suggestions( array(
    200                         'object_id' => $this->group_ids['public'],
    201                         'type'      => 'group-members',
    202                         'term'      => 'smith',
     200                        'group_id' => $this->group_ids['public'],
     201                        'type'     => 'members',
     202                        'term'     => 'smith',
    203203                ) );
    204204
    205205                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    public function test_suggestions_with_type_groupmembers_public_as_id() { 
    207207
    208208        public function test_suggestions_with_type_groupmembers_public_as_slug() {
    209209                $suggestions = bp_core_get_suggestions( array(
    210                         'object_id' => $this->group_slugs['public'],
    211                         'type'      => 'group-members',
    212                         'term'      => 'smith',
     210                        'group_id' => $this->group_slugs['public'],
     211                        'type'     => 'members',
     212                        'term'     => 'smith',
    213213                ) );
    214214
    215215                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    public function test_suggestions_with_type_groupmembers_public_as_slug() { 
    218218        public function test_suggestions_with_type_groupmembers_hidden() {
    219219                // current_user isn't a member of the hidden group
    220220                $suggestions = bp_core_get_suggestions( array(
    221                         'object_id' => $this->group_ids['hidden'],
    222                         'type'      => 'group-members',
    223                         'term'      => 'pig',
     221                        'group_id' => $this->group_ids['hidden'],
     222                        'type'     => 'members',
     223                        'term'     => 'pig',
    224224                ) );
    225225                $this->assertTrue( is_wp_error( $suggestions ) );
    226226
    227227                // "alpaca red" is in the hidden group
    228228                $this->set_current_user( $this->users['alpaca red'] );
    229229                $suggestions = bp_core_get_suggestions( array(
    230                         'object_id' => $this->group_ids['hidden'],
    231                         'type'      => 'group-members',
    232                         'term'      => 'pig',
     230                        'group_id' => $this->group_ids['hidden'],
     231                        'type'     => 'members',
     232                        'term'     => 'pig',
    233233                ) );
    234234                $this->assertEquals( 1, count( $suggestions ) );  // pig
    235235        }
    public function test_suggestions_with_type_groupmembers_hidden() { 
    237237        public function test_suggestions_with_type_groupmembers_private() {
    238238                // current_user isn't a member of the private group
    239239                $suggestions = bp_core_get_suggestions( array(
    240                         'object_id' => $this->group_ids['private'],
    241                         'type'      => 'group-members',
    242                         'term'      => 'cat',
     240                        'group_id' => $this->group_ids['private'],
     241                        'type'     => 'members',
     242                        'term'     => 'cat',
    243243                ) );
    244244                $this->assertTrue( is_wp_error( $suggestions ) );
    245245
    246246                // "caterpillar" is in the private group
    247247                $this->set_current_user( $this->users['caterpillar'] );
    248248                $suggestions = bp_core_get_suggestions( array(
    249                         'object_id' => $this->group_ids['private'],
    250                         'type'      => 'group-members',
    251                         'term'      => 'cat',
     249                        'group_id' => $this->group_ids['private'],
     250                        'type'     => 'members',
     251                        'term'     => 'cat',
    252252                ) );
    253253                $this->assertEquals( 2, count( $suggestions ) );  // cat, caterpillar
    254254        }
    public function test_suggestions_with_bad_type() { 
    343343                $this->assertTrue( is_wp_error( $suggestions ) );
    344344        }
    345345
    346         public function test_suggestions_with_type_groupmembers_and_bad_object_id() {
    347                 // object_id must be a positive integer.
    348                 $suggestions = bp_core_get_suggestions( array(
    349                         'object_id' => -12,
    350                         'type'      => 'group-members',
    351                 ) );
    352                 $this->assertTrue( is_wp_error( $suggestions ) );
    353 
    354                 // object_id can also be a group slug.
     346        public function test_suggestions_with_type_groupmembers_and_bad_group_ids() {
     347                // group_ids must be a positive integer.
    355348                $suggestions = bp_core_get_suggestions( array(
    356                         'object_id' => 'fake-group-slug',
    357                         'type'      => 'group-members',
     349                        'group_id' => -12,
     350                        'type'     => 'members',
    358351                ) );
    359352                $this->assertTrue( is_wp_error( $suggestions ) );
    360353
    361                 // object_id must be set when scope=group
     354                // group_ids can also be a group slug.
    362355                $suggestions = bp_core_get_suggestions( array(
    363                         'type' => 'group-members',
     356                        'group_id' => 'fake-group-slug',
     357                        'type'     => 'members',
    364358                ) );
    365359                $this->assertTrue( is_wp_error( $suggestions ) );
    366360        }
    367361
    368         public function test_suggestions_with_type_members_and_object_id() {
    369                 // object_id cannot be set when scope=global
    370                 $suggestions = bp_core_get_suggestions( array(
    371                         'object_id' => 12,
    372                         'type'      => 'members',
    373                 ) );
    374 
    375                 $this->assertTrue( is_wp_error( $suggestions ) );
    376         }
    377 
    378362        public function test_suggestions_with_bad_term() {
    379363                // a non-empty term is mandatory
    380364                $suggestions = bp_core_get_suggestions( array(
  • src/bp-members/bp-members-functions.php

    -- 
    1.9.3
    
    
    From 75f9285389ffc6293af4520e624667c34803466a Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 20:42:19 +0100
    Subject: [PATCH 11/35] Suggestions: change how we get the display name
    
    The function now used has internal logic for bp_disable_profile_sync(),
    as well as caching.
    ---
     src/bp-members/bp-members-functions.php | 6 +-----
     1 file changed, 1 insertion(+), 5 deletions(-)
    
    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 24f5ddb..9b6eb64 100644
    a b function bp_members_get_suggestions( $args ) { 
    21482148                $result        = new stdClass();
    21492149                $result->ID    = $user->user_nicename;
    21502150                $result->image = get_avatar( $user );
    2151                 $result->name  = $user->display_name;
    2152 
    2153                 if ( bp_disable_profile_sync() ) {
    2154                         $result->name = BP_XProfile_Field::get_fullname( $user->ID );
    2155                 }
     2151                $result->name  = bp_core_get_user_displayname( $user->ID );
    21562152
    21572153                $results[] = $result;
    21582154        }
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From 6617e1c8bbb54b3f6dc296a80fbe39d0be173349 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 20:50:42 +0100
    Subject: [PATCH 12/35] Add missing required parameter to some tests
    
    type was optional in an early iteration :)
    ---
     tests/phpunit/testcases/apis/suggestions.php | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index b2d6274..81d228e 100644
    a b public function test_suggestions_with_type_groupmembers_private() { 
    261261        public function test_suggestions_response_no_matches() {
    262262                $suggestions = bp_core_get_suggestions( array(
    263263                        'term' => 'abcdefghijklmnopqrstuvwxyz',
     264                        'type' => 'members',
    264265                ) );
    265266
    266267                $this->assertInternalType( 'array', $suggestions );
    public function test_suggestions_response_no_matches() { 
    270271        public function test_suggestions_response_single_match() {
    271272                $suggestion = bp_core_get_suggestions( array(
    272273                        'term' => 'zoom',
     274                        'type' => 'members',
    273275                ) );
    274276
    275277                $this->assertInternalType( 'array', $suggestion );
    public function test_suggestions_response_single_match() { 
    286288        public function test_suggestions_response_multiple_matches() {
    287289                $suggestions = bp_core_get_suggestions( array(
    288290                        'term' => 'cat',
     291                        'type' => 'members',
    289292                ) );
    290293
    291294                $this->assertInternalType( 'array', $suggestions );
    public function test_suggestions_response_multiple_matches() { 
    302305        public function test_suggestions_term_is_case_insensitive() {
    303306                $lowercase = bp_core_get_suggestions( array(
    304307                        'term' => 'lisa',
     308                        'type' => 'members',
    305309                ) );
    306310                $this->assertEquals( 1, count( $lowercase ) );
    307311
    308312                $uppercase = bp_core_get_suggestions( array(
    309313                        'term' => 'LISA',
     314                        'type' => 'members',
    310315                ) );
    311316                $this->assertEquals( 1, count( $uppercase ) );
    312317
    public function test_suggestions_term_is_case_insensitive() { 
    317322        public function test_suggestions_response_property_types() {
    318323                $suggestion = bp_core_get_suggestions( array(
    319324                        'term' => 'zoom',
     325                        'type' => 'members',
    320326                ) );
    321327
    322328                $this->assertInternalType( 'array', $suggestion );
    public function test_suggestions_with_bad_term() { 
    363369                // a non-empty term is mandatory
    364370                $suggestions = bp_core_get_suggestions( array(
    365371                        'term' => '',
     372                        'type' => 'members',
    366373                ) );
    367374
    368375                $this->assertTrue( is_wp_error( $suggestions ) );
  • tests/phpunit/testcases/apis/suggestions-nonauth.php

    -- 
    1.9.3
    
    
    From dce81b7dab00a12513ecc1527c4920e39edf394c Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 21:39:12 +0100
    Subject: [PATCH 13/35] Suggestions tests: use $this->create_user() to create
     users
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    factory->user->create doesn’t add xprofile data which we need for these
    tests.
    ---
     tests/phpunit/testcases/apis/suggestions-nonauth.php | 2 +-
     tests/phpunit/testcases/apis/suggestions.php         | 6 +++---
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    index 0c67d17..e21a4af 100644
    a b public function setUp() { 
    2929
    3030                // Create some dummy users.
    3131                foreach( $users as $user ) {
    32                         $this->user_ids[ $user[0] ] = $this->factory->user->create( array(
     32                        $this->user_ids[ $user[0] ] = $this->create_user( array(
    3333                                'display_name' => $user[1],
    3434                                'user_login'   => $user[0],
    3535                        ) );
  • tests/phpunit/testcases/apis/suggestions.php

    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 81d228e..0a1ac10 100644
    a b public function setUp() { 
    1616                parent::setUp();
    1717
    1818                $this->old_user_id  = get_current_user_id();
    19                 $this->current_user = $this->factory->user->create( array(
     19                $this->current_user = $this->create_user( array(
    2020                        'display_name' => 'Katie Parker',
    2121                        'user_login'   => 'admin',
    2222                ) );
    public function setUp() { 
    3838                );
    3939
    4040                // Create some dummy users.
    41                 foreach( $users as $user ) {
    42                         $this->user_ids[ $user[0] ] = $this->factory->user->create( array(
     41                foreach ( $users as $user ) {
     42                        $this->user_ids[ $user[0] ] = $this->create_user( array(
    4343                                'display_name' => $user[1],
    4444                                'user_login'   => $user[0],
    4545                        ) );
  • tests/phpunit/testcases/apis/suggestions-nonauth.php

    -- 
    1.9.3
    
    
    From 5eac207f9230a48e89a939a33a4a68a01934f19a Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 21:43:54 +0100
    Subject: [PATCH 14/35] Whitespace tweaks
    
    ---
     tests/phpunit/testcases/apis/suggestions-nonauth.php | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    index e21a4af..b7d7aaa 100644
    a b public function test_suggestions_with_type_groupmembers_and_only_friends() { 
    8787
    8888        public function test_suggestions_with_type_groupmembers_hidden() {
    8989                $suggestions = bp_core_get_suggestions( array(
    90                         'group_id'  => $this->group_ids['hidden'],
    91                         'type'      => 'members',
    92                         'term'      => 'pig',
     90                        'group_id' => $this->group_ids['hidden'],
     91                        'type'     => 'members',
     92                        'term'     => 'pig',
    9393                ) );
    9494
    9595                $this->assertTrue( is_wp_error( $suggestions ) );
    public function test_suggestions_with_type_groupmembers_hidden() { 
    9797
    9898        public function test_suggestions_with_type_groupmembers_private() {
    9999                $suggestions = bp_core_get_suggestions( array(
    100                         'group_id'  => $this->group_ids['private'],
    101                         'type'      => 'members',
    102                         'term'      => 'cat',
     100                        'group_id' => $this->group_ids['private'],
     101                        'type'     => 'members',
     102                        'term'     => 'cat',
    103103                ) );
    104104
    105105                $this->assertTrue( is_wp_error( $suggestions ) );
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From affc24b90d58dae0c7d327b7ca5350fb77f64d9a Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 21:44:13 +0100
    Subject: [PATCH 15/35] Suggestions: ID property is uppercase
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 0a1ac10..092834a 100644
    a b public function test_suggestions_with_term_as_current_user() { 
    139139                        'term' => 'katie',
    140140                ) );
    141141                $this->assertEquals( 1, count( $suggestions ) );
    142                 $this->assertSame( 'admin', $suggestions[0]->id );
     142                $this->assertSame( 'admin', $suggestions[0]->ID );
    143143        }
    144144
    145145
    public function test_suggestions_term_is_case_insensitive() { 
    315315                ) );
    316316                $this->assertEquals( 1, count( $uppercase ) );
    317317
    318                 $this->assertSame( $lowercase[0]->id, $uppercase[0]->id );
    319                 $this->assertSame( 'zoom', $lowercase[0]->id );
     318                $this->assertSame( $lowercase[0]->ID, $uppercase[0]->ID );
     319                $this->assertSame( 'zoom', $lowercase[0]->ID );
    320320        }
    321321
    322322        public function test_suggestions_response_property_types() {
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From 82ef062a9cb731c7726261946f2a309a18b1cfba Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 21:48:11 +0100
    Subject: [PATCH 16/35] Suggestions: uppercase more IDs
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 092834a..e2f0540 100644
    a b public function test_suggestions_response_single_match() { 
    281281
    282282                $this->assertInternalType( 'object', $suggestion );
    283283                $this->assertAttributeNotEmpty( 'image', $suggestion );
    284                 $this->assertAttributeNotEmpty( 'id', $suggestion );
     284                $this->assertAttributeNotEmpty( 'ID', $suggestion );
    285285                $this->assertAttributeNotEmpty( 'name', $suggestion );
    286286        }
    287287
    public function test_suggestions_response_multiple_matches() { 
    297297                foreach ( $suggestions as $suggestion ) {
    298298                        $this->assertInternalType( 'object', $suggestion );
    299299                        $this->assertAttributeNotEmpty( 'image', $suggestion );
    300                         $this->assertAttributeNotEmpty( 'id', $suggestion );
     300                        $this->assertAttributeNotEmpty( 'ID', $suggestion );
    301301                        $this->assertAttributeNotEmpty( 'name', $suggestion );
    302302                }
    303303        }
    public function test_suggestions_response_property_types() { 
    332332
    333333                $this->assertInternalType( 'object', $suggestion );
    334334                $this->assertAttributeInternalType( 'string', 'image', $suggestion );
    335                 $this->assertAttributeInternalType( 'string', 'id', $suggestion );
     335                $this->assertAttributeInternalType( 'string', 'ID', $suggestion );
    336336                $this->assertAttributeInternalType( 'string', 'name', $suggestion );
    337337        }
    338338
  • src/bp-members/bp-members-functions.php

    -- 
    1.9.3
    
    
    From 192cde4679ff029be90cc96acb839a8610d713c4 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 22:23:45 +0100
    Subject: [PATCH 17/35] Suggestions: image needs to be a direct URL
    
    get_avatar() returns a full `<img>` ta.g
    ---
     src/bp-members/bp-members-functions.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 9b6eb64..8b9bc9a 100644
    a b function bp_members_get_suggestions( $args ) { 
    21472147        foreach ( $user_query->results as $user ) {
    21482148                $result        = new stdClass();
    21492149                $result->ID    = $user->user_nicename;
    2150                 $result->image = get_avatar( $user );
     2150                $result->image = bp_core_fetch_avatar( array( 'html' => false, 'item_id' => $user->ID ) );
    21512151                $result->name  = bp_core_get_user_displayname( $user->ID );
    21522152
    21532153                $results[] = $result;
  • src/bp-members/bp-members-functions.php

    -- 
    1.9.3
    
    
    From e4ac3acd744420cfe58cf05d5a895f9c3c64b7ef Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 22:41:40 +0100
    Subject: [PATCH 18/35] phpDoc tweak
    
    ---
     src/bp-members/bp-members-functions.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 8b9bc9a..45c9377 100644
    a b function bp_live_spammer_login_error() { 
    20932093 * by this particular Suggestions API extension.
    20942094 *
    20952095 * @param array $args {
    2096  *     @type int $group_id If set, only match users that are in this group.
     2096 *     @type int $group_id If set, only match against users that are in this group.
    20972097 *     @type int $limit Maximum number of results to display. Default: 16.
    20982098 *     @type bool $only_friends If true, only match the current user's friends. Default: false.
    20992099 *     @type string $term The suggestion service will try to find results that contain this string.
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From 8453b916780a3817fd002ef0a6a6e34105e82c78 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 22:42:05 +0100
    Subject: [PATCH 19/35] Remove Suggestions test that doesn't match API
    
    Querying groups by slug was removed.
    ---
     tests/phpunit/testcases/apis/suggestions.php | 10 ----------
     1 file changed, 10 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index e2f0540..4bc6a68 100644
    a b public function test_suggestions_with_type_groupmembers_public_as_id() { 
    205205                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    206206        }
    207207
    208         public function test_suggestions_with_type_groupmembers_public_as_slug() {
    209                 $suggestions = bp_core_get_suggestions( array(
    210                         'group_id' => $this->group_slugs['public'],
    211                         'type'     => 'members',
    212                         'term'     => 'smith',
    213                 ) );
    214 
    215                 $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    216         }
    217 
    218208        public function test_suggestions_with_type_groupmembers_hidden() {
    219209                // current_user isn't a member of the hidden group
    220210                $suggestions = bp_core_get_suggestions( array(
  • tests/phpunit/testcases/apis/suggestions-nonauth.php

    -- 
    1.9.3
    
    
    From 4437de02b04ce2b133abb13feea084f05c4d6233 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 23:03:38 +0100
    Subject: [PATCH 20/35] Create test groups from non-current user
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    Otherwise current user is the group admin and has access to the groups
    which weren’t accounted for in the test.
    ---
     tests/phpunit/testcases/apis/suggestions-nonauth.php | 19 ++++++++++++++++---
     tests/phpunit/testcases/apis/suggestions.php         | 19 ++++++++++++++++---
     2 files changed, 32 insertions(+), 6 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    index b7d7aaa..85f9d10 100644
    a b public function setUp() { 
    2424                        array( 'rabbit blue', 'Amber Hooper' ),
    2525                        array( 'smith',       'Robert Bar' ),
    2626                        array( 'snake',       'Eleanor Moore' ),
     27                        array( 'xylo',        'Silver McFadden' ),
    2728                        array( 'zoom',        'Lisa Smithy' ),
    2829                );
    2930
    public function setUp() { 
    4041                $this->group_slugs['private'] = 'tsavo-highway';
    4142
    4243                // Create dummy groups.
    43                 $this->group_ids['hidden']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['hidden'],  'status' => 'hidden' ) );
    44                 $this->group_ids['public']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['public'],  'status' => 'public' ) );
    45                 $this->group_ids['private'] = $this->factory->group->create( array( 'slug' => $this->group_slugs['private'], 'status' => 'private' ) );
     44                $this->group_ids['hidden'] = $this->factory->group->create( array(
     45                        'creator_id' => $this->user_ids['xylo'],
     46                        'slug'       => $this->group_slugs['hidden'],
     47                        'status'     => 'hidden',
     48                ) );
     49                $this->group_ids['public'] = $this->factory->group->create( array(
     50                        'creator_id' => $this->user_ids['xylo'],
     51                        'slug'       => $this->group_slugs['public'],
     52                        'status'     => 'public',
     53                ) );
     54                $this->group_ids['private'] = $this->factory->group->create( array(
     55                        'creator_id' => $this->user_ids['xylo'],
     56                        'slug'       => $this->group_slugs['private'],
     57                        'status'     => 'private',
     58                ) );
    4659
    4760                // Add dummy users to dummy hidden groups.
    4861                groups_join_group( $this->group_ids['hidden'], $this->user_ids['pig'] );
  • tests/phpunit/testcases/apis/suggestions.php

    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 4bc6a68..494854a 100644
    a b public function setUp() { 
    3434                        array( 'rabbit blue', 'Amber Hooper' ),
    3535                        array( 'smith',       'Robert Bar' ),
    3636                        array( 'snake',       'Eleanor Moore' ),
     37                        array( 'xylo',        'Silver McFadden' ),
    3738                        array( 'zoom',        'Lisa Smithy' ),
    3839                );
    3940
    public function setUp() { 
    5657                $this->group_slugs['private'] = 'tsavo-highway';
    5758
    5859                // Create dummy groups.
    59                 $this->group_ids['hidden']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['hidden'],  'status' => 'hidden' ) );
    60                 $this->group_ids['public']  = $this->factory->group->create( array( 'slug' => $this->group_slugs['public'],  'status' => 'public' ) );
    61                 $this->group_ids['private'] = $this->factory->group->create( array( 'slug' => $this->group_slugs['private'], 'status' => 'private' ) );
     60                $this->group_ids['hidden'] = $this->factory->group->create( array(
     61                        'creator_id' => $this->user_ids['xylo'],
     62                        'slug'       => $this->group_slugs['hidden'],
     63                        'status'     => 'hidden',
     64                ) );
     65                $this->group_ids['public'] = $this->factory->group->create( array(
     66                        'creator_id' => $this->user_ids['xylo'],
     67                        'slug'       => $this->group_slugs['public'],
     68                        'status'     => 'public',
     69                ) );
     70                $this->group_ids['private'] = $this->factory->group->create( array(
     71                        'creator_id' => $this->user_ids['xylo'],
     72                        'slug'       => $this->group_slugs['private'],
     73                        'status'     => 'private',
     74                ) );
    6275
    6376                // Add dummy users to dummy hidden groups.
    6477                groups_join_group( $this->group_ids['hidden'], $this->user_ids['pig'] );
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From a0508e2ff186a1eaa542f17d6a174803eae5a04f Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sat, 21 Jun 2014 23:06:57 +0100
    Subject: [PATCH 21/35] Suggestions, tests: fix incorrectly named variables
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 494854a..381c98e 100644
    a b public function test_suggestions_with_type_groupmembers_hidden() { 
    228228                $this->assertTrue( is_wp_error( $suggestions ) );
    229229
    230230                // "alpaca red" is in the hidden group
    231                 $this->set_current_user( $this->users['alpaca red'] );
     231                $this->set_current_user( $this->user_ids['alpaca red'] );
    232232                $suggestions = bp_core_get_suggestions( array(
    233233                        'group_id' => $this->group_ids['hidden'],
    234234                        'type'     => 'members',
    public function test_suggestions_with_type_groupmembers_private() { 
    247247                $this->assertTrue( is_wp_error( $suggestions ) );
    248248
    249249                // "caterpillar" is in the private group
    250                 $this->set_current_user( $this->users['caterpillar'] );
     250                $this->set_current_user( $this->user_ids['caterpillar'] );
    251251                $suggestions = bp_core_get_suggestions( array(
    252252                        'group_id' => $this->group_ids['private'],
    253253                        'type'     => 'members',
  • src/bp-core/bp-core-functions.php

    -- 
    1.9.3
    
    
    From d039b95e6b429057e1e6e0f906e089b8e794f3b0 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 00:03:52 +0100
    Subject: [PATCH 22/35] phpDoc tweaks
    
    ---
     src/bp-core/bp-core-functions.php | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/src/bp-core/bp-core-functions.php b/src/bp-core/bp-core-functions.php
    index 837113a..e565cd0 100644
    a b function bp_nav_menu_get_item_url( $slug ) { 
    19301930 * This is used to power BuddyPress' at-mentions suggestions, but it is flexible enough to be used
    19311931 * for similar kinds of requirements.
    19321932 *
    1933  * If a Component or a third-party plugin wants to provide suggestions for a custom type of object,
     1933 * If a component or a third-party plugin wants to provide suggestions for a custom type of object,
    19341934 * use the bp_suggestions_get_types filter and return an associative array with its key as the new
    19351935 * "type", and its value as a function callback.
    19361936 *
    function bp_nav_menu_get_item_url( $slug ) { 
    19521952 */
    19531953function bp_core_get_suggestions( $args ) {
    19541954        $defaults = array(
    1955                 'limit'     => 16,
    1956                 'type'      => '',
    1957                 'term'      => '',
     1955                'limit' => 16,
     1956                'type'  => '',
     1957                'term'  => '',
    19581958        );
    19591959        $args = wp_parse_args( $args, $defaults );
    19601960
  • src/bp-templates/bp-legacy/buddypress-functions.php

    -- 
    1.9.3
    
    
    From a8b48961249f8d0eb760ccd29d9d7d84b77317c2 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 13:46:40 +0100
    Subject: [PATCH 23/35] Re-implement autosuggest for Messages
    
    ---
     .../bp-legacy/buddypress-functions.php             | 78 ++++++----------------
     1 file changed, 21 insertions(+), 57 deletions(-)
    
    diff --git a/src/bp-templates/bp-legacy/buddypress-functions.php b/src/bp-templates/bp-legacy/buddypress-functions.php
    index 784b2dc..455b60e 100644
    a b function bp_legacy_theme_ajax_messages_delete() { 
    13831383 * @return string HTML.
    13841384 */
    13851385function bp_legacy_theme_ajax_messages_autocomplete_results() {
    1386 
     1386        $limit = isset( $_GET['limit'] ) ? absint( $_GET['limit'] )          : (int) apply_filters( 'bp_autocomplete_max_results', 10 );
     1387        $term  = isset( $_GET['q'] )     ? sanitize_text_field( $_GET['q'] ) : '';
     1388       
    13871389        // Include everyone in the autocomplete, or just friends?
    1388         if ( bp_is_current_component( bp_get_messages_slug() ) )
    1389                 $autocomplete_all = buddypress()->messages->autocomplete_all;
    1390 
    1391         $pag_page     = 1;
    1392         $limit        = (int) $_GET['limit'] ? $_GET['limit'] : apply_filters( 'bp_autocomplete_max_results', 10 );
    1393         $search_terms = isset( $_GET['q'] ) ? $_GET['q'] : '';
    1394 
    1395         $user_query_args = array(
    1396                 'search_terms' => $search_terms,
    1397                 'page'         => intval( $pag_page ),
    1398                 'per_page'     => intval( $limit ),
    1399         );
    1400 
    1401         // If only matching against friends, get an $include param for
    1402         // BP_User_Query
    1403         if ( ! $autocomplete_all && bp_is_active( 'friends' ) ) {
    1404                 $include = BP_Friends_Friendship::get_friend_user_ids( bp_loggedin_user_id() );
    1405 
    1406                 // Ensure zero matches if no friends are found
    1407                 if ( empty( $include ) ) {
    1408                         $include = array( 0 );
    1409                 }
    1410 
    1411                 $user_query_args['include'] = $include;
     1390        if ( bp_is_current_component( bp_get_messages_slug() ) ) {
     1391                $only_friends = ( buddypress()->messages->autocomplete_all === false );
     1392        } else {
     1393                $only_friends = true;
    14121394        }
    14131395
    1414         $user_query = new BP_User_Query( $user_query_args );
    1415 
    1416         // Backward compatibility - if a plugin is expecting a legacy
    1417         // filter, pass the IDs through the filter and requery (groan)
    1418         if ( has_filter( 'bp_core_autocomplete_ids' ) || has_filter( 'bp_friends_autocomplete_ids' ) ) {
    1419                 $found_user_ids = wp_list_pluck( $user_query->results, 'ID' );
    1420 
    1421                 if ( $autocomplete_all ) {
    1422                         $found_user_ids = apply_filters( 'bp_core_autocomplete_ids', $found_user_ids );
    1423                 } else {
    1424                         $found_user_ids = apply_filters( 'bp_friends_autocomplete_ids', $found_user_ids );
    1425                 }
    1426 
    1427                 if ( empty( $found_user_ids ) ) {
    1428                         $found_user_ids = array( 0 );
    1429                 }
    1430 
    1431                 // Repopulate the $user_query variable
    1432                 $user_query = new BP_User_Query( array(
    1433                         'include' => $found_user_ids,
    1434                 ) );
    1435         }
     1396        $suggestions = bp_core_get_suggestions( array(
     1397                'limit'        => $limit,
     1398                'only_friends' => $only_friends,
     1399                'term'         => $term,
     1400                'type'         => 'members',
     1401        ) );
    14361402
    1437         if ( ! empty( $user_query->results ) ) {
    1438                 foreach ( $user_query->results as $user ) {
    1439                         if ( bp_is_username_compatibility_mode() ) {
    1440                                 // Sanitize for spaces. Use urlencode() rather
    1441                                 // than rawurlencode() because %20 breaks JS
    1442                                 $username = urlencode( $user->user_login );
    1443                         } else {
    1444                                 $username = $user->user_nicename;
    1445                         }
     1403        if ( $suggestions && ! is_wp_error( $suggestions ) ) {
     1404                foreach ( $suggestions as $user ) {
    14461405
    14471406                        // Note that the final line break acts as a delimiter for the
    14481407                        // autocomplete javascript and thus should not be removed
    1449                         echo '<span id="link-' . esc_attr( $username ) . '" href="' . bp_core_get_user_domain( $user->ID ) . '"></span>' . bp_core_fetch_avatar( array( 'item_id' => $user->ID, 'type' => 'thumb', 'width' => 15, 'height' => 15, 'alt' => $user->display_name ) ) . ' &nbsp;' . bp_core_get_user_displayname( $user->ID ) . ' (' . esc_html( $username ) . ')' . "\n";
     1408                        printf( '<span id="%s" href="#"></span><img src="%s" style="width: 15px"> &nbsp; %s (%s)' . "\n",
     1409                                esc_attr( 'link-' . $user->ID ),
     1410                                esc_url( $user->image ),
     1411                                esc_html( $user->name ),
     1412                                esc_html( $user->ID )
     1413                        );
    14501414                }
    14511415        }
    14521416
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From bc1e065ec696b65e84d447acdf3ff5a0cb30ddf8 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 17:32:00 +0100
    Subject: [PATCH 24/35] Fix typo in test description
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 381c98e..2facd6c 100644
    a b public function test_suggestions_with_type_groupmembers_and_bad_group_ids() { 
    360360                ) );
    361361                $this->assertTrue( is_wp_error( $suggestions ) );
    362362
    363                 // group_ids can also be a group slug.
     363                // group_ids can't be a group slug.
    364364                $suggestions = bp_core_get_suggestions( array(
    365365                        'group_id' => 'fake-group-slug',
    366366                        'type'     => 'members',
  • src/bp-groups/bp-groups-admin.php

    -- 
    1.9.3
    
    
    From 389540f1d8a2c56a22905fcd425e98afbad46a1d Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 17:44:08 +0100
    Subject: [PATCH 25/35] Re-implement autosuggest for group wp-admin.
    
    First pass. Suggestions API still needs updates to make this work as
    expected.
    ---
     src/bp-groups/bp-groups-admin.php            | 49 +++++++++++++---------------
     tests/phpunit/testcases/apis/suggestions.php |  7 ----
     2 files changed, 23 insertions(+), 33 deletions(-)
    
    diff --git a/src/bp-groups/bp-groups-admin.php b/src/bp-groups/bp-groups-admin.php
    index 46e6a94..899b41f 100644
    a b function bp_groups_admin_get_usernames_from_ids( $user_ids = array() ) { 
    984984function bp_groups_admin_autocomplete_handler() {
    985985
    986986        // Bail if user user shouldn't be here, or is a large network
    987         if ( ! current_user_can( 'bp_moderate' ) || ( is_multisite() && wp_is_large_network( 'users' ) ) )
     987        if ( ! current_user_can( 'bp_moderate' ) || ( is_multisite() && wp_is_large_network( 'users' ) ) ) {
    988988                wp_die( -1 );
     989        }
     990
     991        $term     = isset( $_GET['term'] )     ? sanitize_text_field( $_GET['term'] ) : '';
     992        $group_id = isset( $_GET['group_id'] ) ? absint( $_GET['group_id'] )          : 0;
    989993
    990         $return = array();
     994        if ( ! $term || ! $group_id ) {
     995                wp_die( -1 );
     996        }
    991997
    992         // Exclude current group members
    993         $group_id = isset( $_GET['group_id'] ) ? wp_parse_id_list( $_GET['group_id'] ) : array();
    994         $group_member_query = new BP_Group_Member_Query( array(
    995                 'group_id'        => $group_id,
    996                 'per_page'        => 0, // show all
    997                 'group_role'      => array( 'member', 'mod', 'admin', ),
    998                 'populate_extras' => false,
    999                 'count_total'     => false,
     998        $suggestions = bp_core_get_suggestions( array(
     999                'group_id' => -$group_id,  // A negative value will exclude this group's members from the suggestions.
     1000                'limit'    => 10,
     1001                'term'     => $term,
     1002                'type'     => 'members',
    10001003        ) );
    10011004
    1002         $group_members = ! empty( $group_member_query->results ) ? wp_list_pluck( $group_member_query->results, 'ID' ) : array();
     1005        $matches = array();
    10031006
    1004         $terms = isset( $_GET['term'] ) ? $_GET['term'] : '';
    1005         $users = bp_core_get_users( array(
    1006                 'type'            => 'alphabetical',
    1007                 'search_terms'    => $terms,
    1008                 'exclude'         => $group_members,
    1009                 'per_page'        => 10,
    1010                 'populate_extras' => false
    1011         ) );
     1007        if ( $suggestions && ! is_wp_error( $suggestions ) ) {
     1008                foreach ( $suggestions as $user ) {
    10121009
    1013         foreach ( (array) $users['users'] as $user ) {
    1014                 $return[] = array(
    1015                         /* translators: 1: user_login, 2: user_email */
    1016                         'label' => sprintf( __( '%1$s (%2$s)', 'buddypress' ), bp_is_username_compatibility_mode() ? $user->user_login : $user->user_nicename, $user->user_email ),
    1017                         'value' => $user->user_nicename,
    1018                 );
     1010                        $matches[] = array(
     1011                                // translators: 1: user_login, 2: user_email
     1012                                'label' => sprintf( __( '%1$s (%2$s)', 'buddypress' ), $user->name, $user->ID ),
     1013                                'value' => $user->ID,
     1014                        );
     1015                }
    10191016        }
    10201017
    1021         wp_die( json_encode( $return ) );
     1018        wp_die( json_encode( $matches ) );
    10221019}
    10231020add_action( 'wp_ajax_bp_group_admin_member_autocomplete', 'bp_groups_admin_autocomplete_handler' );
    10241021
  • tests/phpunit/testcases/apis/suggestions.php

    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 2facd6c..c4b845c 100644
    a b public function test_suggestions_with_bad_type() { 
    353353        }
    354354
    355355        public function test_suggestions_with_type_groupmembers_and_bad_group_ids() {
    356                 // group_ids must be a positive integer.
    357                 $suggestions = bp_core_get_suggestions( array(
    358                         'group_id' => -12,
    359                         'type'     => 'members',
    360                 ) );
    361                 $this->assertTrue( is_wp_error( $suggestions ) );
    362 
    363356                // group_ids can't be a group slug.
    364357                $suggestions = bp_core_get_suggestions( array(
    365358                        'group_id' => 'fake-group-slug',
  • src/bp-groups/bp-groups-functions.php

    -- 
    1.9.3
    
    
    From 8be8f55862e11f7da3d13451d390d65c622f01de Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 18:45:19 +0100
    Subject: [PATCH 26/35] API tweaks to fix group wp-admin suggestions.
    
    ---
     src/bp-groups/bp-groups-functions.php   | 17 +++++++++++++----
     src/bp-members/bp-members-functions.php |  2 +-
     2 files changed, 14 insertions(+), 5 deletions(-)
    
    diff --git a/src/bp-groups/bp-groups-functions.php b/src/bp-groups/bp-groups-functions.php
    index a1b27df..15f78bf 100644
    a b function groups_remove_data_for_user( $user_id ) { 
    11661166 * @since BuddyPress (2.1.0)
    11671167 */
    11681168function bp_groups_suggestions_filter_query_args( $query_args, $suggestion_args ) {
    1169         if ( ! $suggestion_args['group_id'] ) {
     1169        if ( ! (int) $suggestion_args['group_id'] ) {
    11701170                return $query_args;
    11711171        }
    11721172
     1173        // Positive integers will restrict the search to members in that group.
     1174        // Negative integers will restrict the search to members in every other group.
     1175        $suggestion_args['group_id'] = (int) $suggestion_args['group_id'];
     1176
    11731177        $the_group = groups_get_group( array(
    1174                 'group_id'        => $suggestion_args['group_id'],
     1178                'group_id'        => absint( $suggestion_args['group_id'] ),
    11751179                'populate_extras' => true,
    11761180        ) );
    11771181
    function bp_groups_suggestions_filter_query_args( $query_args, $suggestion_args 
    11841188                'populate_extras' => false,
    11851189                'type'            => 'alphabetical',
    11861190
    1187                 'group_id'        => $suggestion_args['group_id'],
     1191                'group_id'        => absint( $suggestion_args['group_id'] ),
    11881192        );
    11891193
    11901194        $group_users = new BP_Group_Member_Query( $group_query );
    11911195        if ( $group_users->results ) {
    1192                 $query_args['include'] = wp_list_pluck( $group_users->results, 'ID' );
     1196                if ( $suggestion_args['group_id'] > 0 ) {
     1197                        $query_args['include'] = wp_list_pluck( $group_users->results, 'ID' );
     1198                } else {
     1199                        $query_args['exclude'] = wp_list_pluck( $group_users->results, 'ID' );
     1200                }
     1201
    11931202        } else {
    11941203                $query_args['include'] = array( 0 );
    11951204        }
  • src/bp-members/bp-members-functions.php

    diff --git a/src/bp-members/bp-members-functions.php b/src/bp-members/bp-members-functions.php
    index 45c9377..cccae3c 100644
    a b function bp_members_get_suggestions( $args ) { 
    21112111                'term'         => '',     // Sanitised upstream
    21122112        );
    21132113        $args                 = apply_filters( 'bp_members_get_suggestions_args', wp_parse_args( $args, $defaults ) );
    2114         $args['group_id']     = absint( $args['group_id'] );
     2114        $args['group_id']     = (int) $args['group_id'];
    21152115        $args['only_friends'] = (bool) $args['only_friends'];
    21162116
    21172117
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From 96541bd37c69b7213c001ab5d7fc55f14977075b Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:03:57 +0100
    Subject: [PATCH 27/35] Minor whitespace tweaks
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index c4b845c..651cfba 100644
    a b public function test_suggestions_with_type_groupmembers_hidden() { 
    238238        }
    239239
    240240        public function test_suggestions_with_type_groupmembers_private() {
    241                 // current_user isn't a member of the private group
     241                // current_user isn't a member of the private group.
    242242                $suggestions = bp_core_get_suggestions( array(
    243243                        'group_id' => $this->group_ids['private'],
    244244                        'type'     => 'members',
    public function test_suggestions_with_type_groupmembers_and_bad_group_ids() { 
    358358                        'group_id' => 'fake-group-slug',
    359359                        'type'     => 'members',
    360360                ) );
     361
    361362                $this->assertTrue( is_wp_error( $suggestions ) );
    362363        }
    363364
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From 9434ddc992cb554a98d3220e1812ff72d5047a36 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:17:49 +0100
    Subject: [PATCH 28/35] Tests for group wp-admin auto-suggest
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 78 ++++++++++++++++++++++++++++
     1 file changed, 78 insertions(+)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 651cfba..7bfc961 100644
    a b public function setUp() { 
    8080                // Add dummy users to dummy public groups.
    8181                groups_join_group( $this->group_ids['public'], $this->current_user );
    8282                groups_join_group( $this->group_ids['public'], $this->user_ids['aardvark'] );
     83                groups_join_group( $this->group_ids['public'], $this->user_ids['alpaca red'] );
     84                groups_join_group( $this->group_ids['public'], $this->user_ids['cat'] );
    8385                groups_join_group( $this->group_ids['public'], $this->user_ids['smith'] );
    8486
    8587                // Add dummy users to dummy private groups.
    public function test_suggestions_with_type_groupmembers_private() { 
    257259        }
    258260
    259261
     262        public function test_suggestions_with_type_groupmembers_public_and_exclude_group_from_results() {
     263                $suggestions = bp_core_get_suggestions( array(
     264                        'group_id' => $this->group_ids['public'],
     265                        'type'     => 'members',
     266                        'term'     => 'smith',
     267                ) );
     268                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
     269
     270                $suggestions = bp_core_get_suggestions( array(
     271                        'group_id' => -$this->group_ids['public'],
     272                        'type'     => 'members',
     273                        'term'     => 'smith',
     274                ) );
     275                $this->assertEquals( 1, count( $suggestions ) );  // zoom
     276        }
     277
     278        public function test_suggestions_with_type_groupmembers_private_and_exclude_group_from_results() {
     279                // current_user isn't a member of the private group.
     280                $suggestions = bp_core_get_suggestions( array(
     281                        'group_id' => -$this->group_ids['private'],
     282                        'type'     => 'members',
     283                        'term'     => 'cat',
     284                ) );
     285                $this->assertTrue( is_wp_error( $suggestions ) );
     286
     287
     288                $this->set_current_user( $this->user_ids['caterpillar'] );
     289
     290                // "cat" is in the private group, so won't show up here.
     291                $suggestions = bp_core_get_suggestions( array(
     292                        'group_id' => -$this->group_ids['private'],
     293                        'type'     => 'members',
     294                        'term'     => 'cat',
     295                ) );
     296                $this->assertEmpty( $suggestions );
     297
     298                // "zoo" is not the private group, so will show up here.
     299                $suggestions = bp_core_get_suggestions( array(
     300                        'group_id' => -$this->group_ids['private'],
     301                        'type'     => 'members',
     302                        'term'     => 'zoo',
     303                ) );
     304                $this->assertEquals( 1, count( $suggestions ) );  // zoo
     305        }
     306
     307        public function test_suggestions_with_type_groupmembers_hidden_and_exclude_group_from_results() {
     308                // current_user isn't a member of the hidden group.
     309                $suggestions = bp_core_get_suggestions( array(
     310                        'group_id' => $this->group_ids['hidden'],
     311                        'type'     => 'members',
     312                        'term'     => 'pig',
     313                ) );
     314                $this->assertTrue( is_wp_error( $suggestions ) );
     315
     316
     317                $this->set_current_user( $this->user_ids['alpaca red'] );
     318
     319                // "alpaca red" is in the hidden group, so won't show up here.
     320                $suggestions = bp_core_get_suggestions( array(
     321                        'group_id' => -$this->group_ids['hidden'],
     322                        'type'     => 'members',
     323                        'term'     => 'alpaca red',
     324                ) );
     325                $this->assertEmpty( $suggestions );
     326
     327                // "zoo" is not the hidden group, so will show up here.
     328                $suggestions = bp_core_get_suggestions( array(
     329                        'group_id' => -$this->group_ids['hidden'],
     330                        'type'     => 'members',
     331                        'term'     => 'zoo',
     332                ) );
     333                die(var_dump('too many', $suggestions));
     334                $this->assertEquals( 1, count( $suggestions ) );  // zoo
     335        }
     336
     337
    260338        /**
    261339         * These next tests check the format of the response from the Suggestions API.
    262340         */
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From 726128795a67253052ce28836c79ce4586ce0c63 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:22:30 +0100
    Subject: [PATCH 29/35] Remove debug
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 7bfc961..974b79a 100644
    a b public function test_suggestions_with_type_groupmembers_hidden_and_exclude_group 
    330330                        'type'     => 'members',
    331331                        'term'     => 'zoo',
    332332                ) );
    333                 die(var_dump('too many', $suggestions));
     333                $this->assertFalse( is_wp_error( $suggestions ) );
    334334                $this->assertEquals( 1, count( $suggestions ) );  // zoo
    335335        }
    336336
  • tests/phpunit/testcases/apis/suggestions-nonauth.php

    -- 
    1.9.3
    
    
    From 084653598ae4b600efffc65ed815e189513ed25e Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:23:09 +0100
    Subject: [PATCH 30/35] Suggestions tests: sync group members to non-auth tests
    
    ---
     tests/phpunit/testcases/apis/suggestions-nonauth.php | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    index 85f9d10..4f7366b 100644
    a b public function setUp() { 
    6262                groups_join_group( $this->group_ids['hidden'], $this->user_ids['alpaca red'] );
    6363
    6464                // Add dummy users to dummy public groups.
     65                groups_join_group( $this->group_ids['public'], $this->current_user );
    6566                groups_join_group( $this->group_ids['public'], $this->user_ids['aardvark'] );
     67                groups_join_group( $this->group_ids['public'], $this->user_ids['alpaca red'] );
     68                groups_join_group( $this->group_ids['public'], $this->user_ids['cat'] );
    6669                groups_join_group( $this->group_ids['public'], $this->user_ids['smith'] );
    6770
    6871                // Add dummy users to dummy private groups.
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From e01ab4f108f46c41569db673476dc600c2d923a2 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:24:52 +0100
    Subject: [PATCH 31/35] Suggestions tests: count() can lie
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    count() on a WP_Error object can return 1. This is making some tests
    pass accidentally. Check `is_wp_error` for each test just to be very
    sure we don’t let anything similar through in future.
    ---
     tests/phpunit/testcases/apis/suggestions.php | 27 +++++++++++++++++++++++++++
     1 file changed, 27 insertions(+)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index 974b79a..dbc82fd 100644
    a b public function test_suggestions_with_type_members() { 
    101101                        'term' => 'smith',
    102102                ) );
    103103
     104                $this->assertFalse( is_wp_error( $suggestions ) );
    104105                $this->assertEquals( 3, count( $suggestions ) );  // aardvark, smith, zoom.
    105106        }
    106107
    public function test_suggestions_with_type_members_and_limit() { 
    111112                        'term'  => 'smith',
    112113                ) );
    113114
     115                $this->assertFalse( is_wp_error( $suggestions ) );
    114116                $this->assertEquals( 2, count( $suggestions ) );  // two of: aardvark, smith, zoom.
    115117        }
    116118
    public function test_suggestions_with_type_members_and_only_friends() { 
    120122                        'type'         => 'members',
    121123                        'term'         => 'smith',
    122124                ) );
     125                $this->assertFalse( is_wp_error( $suggestions ) );
    123126                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
    124127
    125128                $suggestions = bp_core_get_suggestions( array(
    public function test_suggestions_with_type_members_and_only_friends() { 
    127130                        'type'         => 'members',
    128131                        'term'         => 'cat',
    129132                ) );
     133                $this->assertFalse( is_wp_error( $suggestions ) );
    130134                $this->assertEquals( 2, count( $suggestions ) );  // cat, caterpillar.
    131135        }
    132136
    public function test_suggestions_with_type_members_and_term_as_displayname() { 
    136140                        'term' => 'aardvark',
    137141                ) );
    138142
     143                $this->assertFalse( is_wp_error( $suggestions ) );
    139144                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
    140145        }
    141146
    public function test_suggestions_with_type_members_and_term_as_usernicename() { 
    145150                        'term' => 'eleanor',
    146151                ) );
    147152
     153                $this->assertFalse( is_wp_error( $suggestions ) );
    148154                $this->assertEquals( 1, count( $suggestions ) );  // snake.
    149155        }
    150156
    public function test_suggestions_with_term_as_current_user() { 
    153159                        'type' => 'members',
    154160                        'term' => 'katie',
    155161                ) );
     162
     163                $this->assertFalse( is_wp_error( $suggestions ) );
    156164                $this->assertEquals( 1, count( $suggestions ) );
    157165                $this->assertSame( 'admin', $suggestions[0]->ID );
    158166        }
    public function test_suggestions_with_type_groupmembers_public() { 
    165173                        'term'     => 'smith',
    166174                ) );
    167175
     176                $this->assertFalse( is_wp_error( $suggestions ) );
    168177                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    169178        }
    170179
    public function test_suggestions_with_type_groupmembers_public_and_limit() { 
    176185                        'term'     => 'smith',
    177186                ) );
    178187
     188                $this->assertFalse( is_wp_error( $suggestions ) );
    179189                $this->assertEquals( 1, count( $suggestions ) );  // one of: aardvark, smith.
    180190        }
    181191
    public function test_suggestions_with_type_groupmembers_public_and_only_friends( 
    187197                        'term'         => 'smith',
    188198                ) );
    189199
     200                $this->assertFalse( is_wp_error( $suggestions ) );
    190201                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
    191202        }
    192203
    public function test_suggestions_with_type_groupmembers_public_and_term_as_displ 
    197208                        'term'     => 'aardvark',
    198209                ) );
    199210
     211                $this->assertFalse( is_wp_error( $suggestions ) );
    200212                $this->assertEquals( 1, count( $suggestions ) );  // aardvark.
    201213        }
    202214
    public function test_suggestions_with_type_groupmembers_public_and_term_as_usern 
    207219                        'term'     => 'robert',
    208220                ) );
    209221
     222                $this->assertFalse( is_wp_error( $suggestions ) );
    210223                $this->assertEquals( 1, count( $suggestions ) );  // smith.
    211224        }
    212225
    public function test_suggestions_with_type_groupmembers_public_as_id() { 
    217230                        'term'     => 'smith',
    218231                ) );
    219232
     233                $this->assertFalse( is_wp_error( $suggestions ) );
    220234                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    221235        }
    222236
    public function test_suggestions_with_type_groupmembers_hidden() { 
    236250                        'type'     => 'members',
    237251                        'term'     => 'pig',
    238252                ) );
     253                $this->assertFalse( is_wp_error( $suggestions ) );
    239254                $this->assertEquals( 1, count( $suggestions ) );  // pig
    240255        }
    241256
    public function test_suggestions_with_type_groupmembers_private() { 
    255270                        'type'     => 'members',
    256271                        'term'     => 'cat',
    257272                ) );
     273                $this->assertFalse( is_wp_error( $suggestions ) );
    258274                $this->assertEquals( 2, count( $suggestions ) );  // cat, caterpillar
    259275        }
    260276
    public function test_suggestions_with_type_groupmembers_public_and_exclude_group 
    265281                        'type'     => 'members',
    266282                        'term'     => 'smith',
    267283                ) );
     284                $this->assertFalse( is_wp_error( $suggestions ) );
    268285                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
    269286
    270287                $suggestions = bp_core_get_suggestions( array(
    public function test_suggestions_with_type_groupmembers_public_and_exclude_group 
    272289                        'type'     => 'members',
    273290                        'term'     => 'smith',
    274291                ) );
     292                $this->assertFalse( is_wp_error( $suggestions ) );
    275293                $this->assertEquals( 1, count( $suggestions ) );  // zoom
    276294        }
    277295
    public function test_suggestions_with_type_groupmembers_private_and_exclude_grou 
    293311                        'type'     => 'members',
    294312                        'term'     => 'cat',
    295313                ) );
     314                $this->assertFalse( is_wp_error( $suggestions ) );
    296315                $this->assertEmpty( $suggestions );
    297316
    298317                // "zoo" is not the private group, so will show up here.
    public function test_suggestions_with_type_groupmembers_private_and_exclude_grou 
    301320                        'type'     => 'members',
    302321                        'term'     => 'zoo',
    303322                ) );
     323                $this->assertFalse( is_wp_error( $suggestions ) );
    304324                $this->assertEquals( 1, count( $suggestions ) );  // zoo
    305325        }
    306326
    public function test_suggestions_with_type_groupmembers_hidden_and_exclude_group 
    322342                        'type'     => 'members',
    323343                        'term'     => 'alpaca red',
    324344                ) );
     345                $this->assertFalse( is_wp_error( $suggestions ) );
    325346                $this->assertEmpty( $suggestions );
    326347
    327348                // "zoo" is not the hidden group, so will show up here.
    public function test_suggestions_response_no_matches() { 
    345366                        'type' => 'members',
    346367                ) );
    347368
     369                $this->assertFalse( is_wp_error( $suggestions ) );
    348370                $this->assertInternalType( 'array', $suggestions );
    349371                $this->assertEmpty( $suggestions );
    350372        }
    public function test_suggestions_response_single_match() { 
    355377                        'type' => 'members',
    356378                ) );
    357379
     380                $this->assertFalse( is_wp_error( $suggestions ) );
    358381                $this->assertInternalType( 'array', $suggestion );
    359382                $this->assertNotEmpty( $suggestion );
    360383
    public function test_suggestions_response_multiple_matches() { 
    372395                        'type' => 'members',
    373396                ) );
    374397
     398                $this->assertFalse( is_wp_error( $suggestions ) );
    375399                $this->assertInternalType( 'array', $suggestions );
    376400                $this->assertNotEmpty( $suggestions );
    377401
    public function test_suggestions_term_is_case_insensitive() { 
    388412                        'term' => 'lisa',
    389413                        'type' => 'members',
    390414                ) );
     415                $this->assertFalse( is_wp_error( $suggestions ) );
    391416                $this->assertEquals( 1, count( $lowercase ) );
    392417
    393418                $uppercase = bp_core_get_suggestions( array(
    394419                        'term' => 'LISA',
    395420                        'type' => 'members',
    396421                ) );
     422                $this->assertFalse( is_wp_error( $suggestions ) );
    397423                $this->assertEquals( 1, count( $uppercase ) );
    398424
    399425                $this->assertSame( $lowercase[0]->ID, $uppercase[0]->ID );
    public function test_suggestions_response_property_types() { 
    406432                        'type' => 'members',
    407433                ) );
    408434
     435                $this->assertFalse( is_wp_error( $suggestions ) );
    409436                $this->assertInternalType( 'array', $suggestion );
    410437                $this->assertNotEmpty( $suggestion );
    411438
  • tests/phpunit/testcases/apis/suggestions-nonauth.php

    -- 
    1.9.3
    
    
    From cbaf3a8a2c972bd01d2e6747f7a53ccf67d02c1d Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:29:17 +0100
    Subject: [PATCH 32/35] Remove copypasta from 0846535
    
    ---
     tests/phpunit/testcases/apis/suggestions-nonauth.php | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    index 4f7366b..f953264 100644
    a b public function setUp() { 
    6262                groups_join_group( $this->group_ids['hidden'], $this->user_ids['alpaca red'] );
    6363
    6464                // Add dummy users to dummy public groups.
    65                 groups_join_group( $this->group_ids['public'], $this->current_user );
    6665                groups_join_group( $this->group_ids['public'], $this->user_ids['aardvark'] );
    6766                groups_join_group( $this->group_ids['public'], $this->user_ids['alpaca red'] );
    6867                groups_join_group( $this->group_ids['public'], $this->user_ids['cat'] );
  • tests/phpunit/testcases/apis/suggestions.php

    -- 
    1.9.3
    
    
    From e0699342f99508312b8612637ef9009444bca646 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:32:47 +0100
    Subject: [PATCH 33/35] More copypasta
    
    ---
     tests/phpunit/testcases/apis/suggestions.php | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions.php b/tests/phpunit/testcases/apis/suggestions.php
    index dbc82fd..c551a33 100644
    a b public function test_suggestions_response_single_match() { 
    377377                        'type' => 'members',
    378378                ) );
    379379
    380                 $this->assertFalse( is_wp_error( $suggestions ) );
     380                $this->assertFalse( is_wp_error( $suggestion ) );
    381381                $this->assertInternalType( 'array', $suggestion );
    382382                $this->assertNotEmpty( $suggestion );
    383383
    public function test_suggestions_term_is_case_insensitive() { 
    412412                        'term' => 'lisa',
    413413                        'type' => 'members',
    414414                ) );
    415                 $this->assertFalse( is_wp_error( $suggestions ) );
     415                $this->assertFalse( is_wp_error( $lowercase ) );
    416416                $this->assertEquals( 1, count( $lowercase ) );
    417417
    418418                $uppercase = bp_core_get_suggestions( array(
    419419                        'term' => 'LISA',
    420420                        'type' => 'members',
    421421                ) );
    422                 $this->assertFalse( is_wp_error( $suggestions ) );
     422                $this->assertFalse( is_wp_error( $uppercase ) );
    423423                $this->assertEquals( 1, count( $uppercase ) );
    424424
    425425                $this->assertSame( $lowercase[0]->ID, $uppercase[0]->ID );
    public function test_suggestions_response_property_types() { 
    432432                        'type' => 'members',
    433433                ) );
    434434
    435                 $this->assertFalse( is_wp_error( $suggestions ) );
     435                $this->assertFalse( is_wp_error( $suggestion ) );
    436436                $this->assertInternalType( 'array', $suggestion );
    437437                $this->assertNotEmpty( $suggestion );
    438438
  • tests/phpunit/testcases/apis/suggestions-nonauth.php

    -- 
    1.9.3
    
    
    From 12995d9a257a9a5fd43b65ae23bd8c725586b636 Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 19:43:17 +0100
    Subject: [PATCH 34/35] Suggestions: grp members exclude test for non-auth
    
    ---
     .../phpunit/testcases/apis/suggestions-nonauth.php | 36 ++++++++++++++++++++++
     1 file changed, 36 insertions(+)
    
    diff --git a/tests/phpunit/testcases/apis/suggestions-nonauth.php b/tests/phpunit/testcases/apis/suggestions-nonauth.php
    index f953264..a16fb8e 100644
    a b public function test_suggestions_with_type_groupmembers_private() { 
    119119
    120120                $this->assertTrue( is_wp_error( $suggestions ) );
    121121        }
     122
     123        public function test_suggestions_with_type_groupmembers_public_and_exclude_group_from_results() {
     124                $suggestions = bp_core_get_suggestions( array(
     125                        'group_id' => $this->group_ids['public'],
     126                        'type'     => 'members',
     127                        'term'     => 'smith',
     128                ) );
     129                $this->assertFalse( is_wp_error( $suggestions ) );
     130                $this->assertEquals( 2, count( $suggestions ) );  // aardvark, smith.
     131
     132                $suggestions = bp_core_get_suggestions( array(
     133                        'group_id' => -$this->group_ids['public'],
     134                        'type'     => 'members',
     135                        'term'     => 'smith',
     136                ) );
     137                $this->assertFalse( is_wp_error( $suggestions ) );
     138                $this->assertEquals( 1, count( $suggestions ) );  // zoom
     139        }
     140
     141        public function test_suggestions_with_type_groupmembers_private_and_exclude_group_from_results() {
     142                $suggestions = bp_core_get_suggestions( array(
     143                        'group_id' => -$this->group_ids['private'],
     144                        'type'     => 'members',
     145                        'term'     => 'cat',
     146                ) );
     147                $this->assertTrue( is_wp_error( $suggestions ) );  // no access to group.
     148        }
     149
     150        public function test_suggestions_with_type_groupmembers_hidden_and_exclude_group_from_results() {
     151                $suggestions = bp_core_get_suggestions( array(
     152                        'group_id' => $this->group_ids['hidden'],
     153                        'type'     => 'members',
     154                        'term'     => 'pig',
     155                ) );
     156                $this->assertTrue( is_wp_error( $suggestions ) );  // no access to group.
     157        }
    122158}
     159 No newline at end of file
  • src/bp-groups/bp-groups-functions.php

    -- 
    1.9.3
    
    
    From 7813626a7a28bcfd1208bc5968587ec26089068b Mon Sep 17 00:00:00 2001
    From: Paul Gibbs <paul@byotos.com>
    Date: Sun, 22 Jun 2014 20:08:04 +0100
    Subject: [PATCH 35/35] Suggestions: group member queries need roles set
    
    ---
     src/bp-groups/bp-groups-functions.php | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/src/bp-groups/bp-groups-functions.php b/src/bp-groups/bp-groups-functions.php
    index 15f78bf..a9edf9b 100644
    a b function bp_groups_suggestions_filter_query_args( $query_args, $suggestion_args 
    11881188                'populate_extras' => false,
    11891189                'type'            => 'alphabetical',
    11901190
     1191                'page'            => 1,
    11911192                'group_id'        => absint( $suggestion_args['group_id'] ),
     1193                'group_role'      => array( 'admin', 'member', 'mod' ),
    11921194        );
    11931195
    11941196        $group_users = new BP_Group_Member_Query( $group_query );