Skip to:
Content

BuddyPress.org

Changeset 13427


Ignore:
Timestamp:
02/23/2023 12:04:36 AM (15 months ago)
Author:
imath
Message:

Improve comparison consistency in BP_Friends_Friendship

  • Fix a bug introduced in [13092] making sure to cast IDs retrieved by $wpdb->results() as integers when comparing them to another integer (user ID).
  • Use strong comparisons everywhere in the class.
  • Add unit tests.

Props boonebgorges

See #8844 (trunk)
Closes https://github.com/buddypress/buddypress/pull/68

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-friends/classes/class-bp-friends-friendship.php

    r13414 r13427  
    266266        if ( empty( $user_id ) ) {
    267267            $user_id = bp_loggedin_user_id();
     268        }
     269
     270        $friendships = array();
     271        $operator    = strtoupper( $operator );
     272
     273        if ( ! in_array( $operator, array( 'AND', 'OR', 'NOT' ), true ) ) {
     274            return $friendships;
    268275        }
    269276
     
    301308        }
    302309
     310        $int_keys  = array( 'id', 'initiator_user_id', 'friend_user_id' );
     311        $bool_keys = array( 'is_confirmed', 'is_limited' );
     312
    303313        // Assemble filter array.
    304314        $filters = wp_array_slice_assoc( $r, array( 'id', 'initiator_user_id', 'friend_user_id', 'is_confirmed', 'is_limited' ) );
     
    306316            if ( is_null( $filter_value ) ) {
    307317                unset( $filters[ $filter_name ] );
     318            } elseif ( in_array( $filter_name, $int_keys, true ) ) {
     319                $filters[ $filter_name ] = (int) $filter_value;
     320            } else {
     321                $filters[ $filter_name ] = (bool) $filter_value;
    308322            }
    309323        }
    310324
    311325        // Populate friendship array from cache, and normalize.
    312         $friendships = array();
    313         $int_keys    = array( 'id', 'initiator_user_id', 'friend_user_id' );
    314         $bool_keys   = array( 'is_confirmed', 'is_limited' );
    315326        foreach ( $friendship_ids as $friendship_id ) {
    316327            // Create a limited BP_Friends_Friendship object (don't fetch the user details).
     
    333344
    334345            // We need to support the same operators as wp_list_filter().
    335             if ( 'OR' == $operator || 'NOT' == $operator ) {
     346            if ( 'OR' === $operator || 'NOT' === $operator ) {
    336347                $matched = 0;
    337348
    338349                foreach ( $filters as $filter_name => $filter_value ) {
    339                     if ( isset( $friendship->{$filter_name} ) && $filter_value == $friendship->{$filter_name} ) {
     350                    if ( isset( $friendship->{$filter_name} ) && $filter_value === $friendship->{$filter_name} ) {
    340351                        $matched++;
    341352                    }
    342353                }
    343354
    344                 if ( ( 'OR' == $operator && $matched > 0 )
    345                   || ( 'NOT' == $operator && 0 == $matched ) ) {
     355                if ( ( 'OR' === $operator && $matched > 0 )
     356                  || ( 'NOT' === $operator && 0 === $matched ) ) {
    346357                    $friendships[ $friendship->id ] = $friendship;
    347358                }
     
    353364                 */
    354365                foreach ( $filters as $filter_name => $filter_value ) {
    355                     if ( ! isset( $friendship->{$filter_name} ) || $filter_value != $friendship->{$filter_name} ) {
     366                    if ( ! isset( $friendship->{$filter_name} ) || $filter_value !== $friendship->{$filter_name} ) {
    356367                        continue 2;
    357368                    }
     
    429440
    430441        $friendships = self::get_friendships( $user_id, $args );
     442        $user_id     = (int) $user_id;
    431443
    432444        $fids = array();
    433445        foreach ( $friendships as $friendship ) {
     446            $friend_id = $friendship->friend_user_id;
     447            if ( $friendship->friend_user_id === $user_id ) {
     448                $friend_id = $friendship->initiator_user_id;
     449            }
     450
    434451            if ( ! empty( $assoc_arr ) ) {
    435                 $fids[] = array( 'user_id' => ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id );
     452                $fids[] = array( 'user_id' => $friend_id );
    436453            } else {
    437                 $fids[] = ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id;
     454                $fids[] = $friend_id;
    438455            }
    439456        }
     
    633650
    634651        // Can't friend yourself.
    635         if ( $initiator_userid === $possible_friend_userid ) {
     652        if ( (int) $initiator_userid === (int) $possible_friend_userid ) {
    636653            return 'not_friends';
    637654        }
     
    658675
    659676        $bp                  = buddypress();
     677        $user_id             = (int) $user_id;
    660678        $possible_friend_ids = wp_parse_id_list( $possible_friend_ids );
    661679
     
    928946        $sql     = $wpdb->prepare( "SELECT friend_user_id, initiator_user_id FROM {$bp->friends->table_name} WHERE (friend_user_id = %d || initiator_user_id = %d) && is_confirmed = 1 ORDER BY rand() LIMIT %d", $user_id, $user_id, $total_friends );
    929947        $results = $wpdb->get_results( $sql );
     948        $user_id = (int) $user_id;
    930949
    931950        for ( $i = 0, $count = count( $results ); $i < $count; ++$i ) {
    932             $fids[] = ( $results[ $i ]->friend_user_id === $user_id ) ? $results[ $i ]->initiator_user_id : $results[ $i ]->friend_user_id;
     951            $friend_user_id    = (int) $results[ $i ]->friend_user_id;
     952            $initiator_user_id = (int) $results[ $i ]->initiator_user_id;
     953
     954            if ( $friend_user_id === $user_id ) {
     955                $fids[] = $initiator_user_id;
     956            } else {
     957                $fids[] = $friend_user_id;
     958            }
    933959        }
    934960
     
    10451071        global $wpdb;
    10461072
    1047         $bp = buddypress();
     1073        $bp      = buddypress();
     1074        $user_id = (int) $user_id;
    10481075
    10491076        // Get all friendships, of any status, for the user.
     
    10541081            $friendship_ids[] = $friendship->id;
    10551082            if ( $friendship->is_confirmed ) {
    1056                 $friend_ids[] = ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id;
     1083                if ( $friendship->friend_user_id === $user_id ) {
     1084                    $friend_ids[] = $friendship->initiator_user_id;
     1085                } else {
     1086                    $friend_ids[] = $friendship->friend_user_id;
     1087                }
    10571088            }
    10581089        }
  • trunk/tests/phpunit/testcases/friends/class-bp-friends-friendship.php

    r13086 r13427  
    192192        $this->assertEquals( $first_query_count, $wpdb->num_queries );
    193193    }
     194
     195    /**
     196     * @ticket BP8844
     197     */
     198    public function test_get_random_friends() {
     199        $user_id = self::factory()->user->create();
     200        $friends = self::factory()->user->create_many( 4 );
     201
     202        foreach ( $friends as $initiator_id ) {
     203            friends_add_friend( $initiator_id, $user_id, true );
     204        }
     205
     206        $random = BP_Friends_Friendship::get_random_friends( $user_id, 4 );
     207        $this->assertFalse( in_array( $user_id, $random, true ), 'The requested user id should not be listed into random friends' );
     208        $this->assertTrue( 4 === count( $random ) );
     209    }
     210
     211    /**
     212     * @ticket BP8844
     213     */
     214    public function test_get_friend_user_ids() {
     215        $user_id = self::factory()->user->create();
     216        $friends = self::factory()->user->create_many( 4 );
     217
     218        foreach ( $friends as $initiator_id ) {
     219            friends_add_friend( $initiator_id, $user_id, true );
     220        }
     221
     222        $friend_user_ids = BP_Friends_Friendship::get_friend_user_ids( $user_id );
     223        $this->assertFalse( in_array( $user_id, $friend_user_ids, true ), 'The requested user id should not be listed into random friends' );
     224        $this->assertTrue( 4 === count( $friend_user_ids ) );
     225    }
     226
     227    /**
     228     * @ticket BP8844
     229     */
     230    public function test_delete_all_for_user() {
     231        $user_id = self::factory()->user->create();
     232        $friends = self::factory()->user->create_many( 4 );
     233
     234        foreach ( $friends as $initiator_id ) {
     235            friends_add_friend( $initiator_id, $user_id, true );
     236        }
     237
     238        BP_Friends_Friendship::delete_all_for_user( $user_id );
     239        $friend_user_ids = BP_Friends_Friendship::get_friendship_ids_for_user( $user_id );
     240        $this->assertEmpty( $friend_user_ids );
     241    }
     242
     243    /**
     244     * @ticket BP8844
     245     */
     246    public function test_get_friendships() {
     247        $u1 = self::factory()->user->create();
     248        $u2 = self::factory()->user->create();
     249        $u3 = self::factory()->user->create();
     250
     251        friends_add_friend( $u2, $u1, false );
     252        friends_add_friend( $u3, $u1, true );
     253
     254        $friendships = BP_Friends_Friendship::get_friendships( $u1, array( 'initiator_user_id' => $u2 ), 'not' );
     255        $friendship = reset( $friendships );
     256        $this->assertTrue( $u3 === $friendship->initiator_user_id && 1 === count( $friendships ) );
     257
     258        $friendships = BP_Friends_Friendship::get_friendships( $u1, array( 'initiator_user_id' => $u3, 'is_confirmed' => 0 ), 'or' );
     259        $this->assertTrue( 2 === count( $friendships ) );
     260    }
    194261}
Note: See TracChangeset for help on using the changeset viewer.