Skip to:
Content

BuddyPress.org

Changeset 13428


Ignore:
Timestamp:
02/23/2023 12:18:50 AM (4 years 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

Fixes #8844 (branch 11.0)

Location:
branches/10.0
Files:
2 edited

Legend:

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

    r13147 r13428  
    268268                if ( empty( $user_id ) ) {
    269269                        $user_id = bp_loggedin_user_id();
     270                }
     271
     272                $friendships = array();
     273                $operator    = strtoupper( $operator );
     274
     275                if ( ! in_array( $operator, array( 'AND', 'OR', 'NOT' ), true ) ) {
     276                        return $friendships;
    270277                }
    271278
     
    303310                }
    304311
     312                $int_keys  = array( 'id', 'initiator_user_id', 'friend_user_id' );
     313                $bool_keys = array( 'is_confirmed', 'is_limited' );
     314
    305315                // Assemble filter array.
    306316                $filters = wp_array_slice_assoc( $r, array( 'id', 'initiator_user_id', 'friend_user_id', 'is_confirmed', 'is_limited' ) );
     
    308318                        if ( is_null( $filter_value ) ) {
    309319                                unset( $filters[ $filter_name ] );
     320                        } elseif ( in_array( $filter_name, $int_keys, true ) ) {
     321                                $filters[ $filter_name ] = (int) $filter_value;
     322                        } else {
     323                                $filters[ $filter_name ] = (bool) $filter_value;
    310324                        }
    311325                }
    312326
    313327                // Populate friendship array from cache, and normalize.
    314                 $friendships = array();
    315                 $int_keys    = array( 'id', 'initiator_user_id', 'friend_user_id' );
    316                 $bool_keys   = array( 'is_confirmed', 'is_limited' );
    317328                foreach ( $friendship_ids as $friendship_id ) {
    318329                        // Create a limited BP_Friends_Friendship object (don't fetch the user details).
     
    335346
    336347                        // We need to support the same operators as wp_list_filter().
    337                         if ( 'OR' == $operator || 'NOT' == $operator ) {
     348                        if ( 'OR' === $operator || 'NOT' === $operator ) {
    338349                                $matched = 0;
    339350
    340351                                foreach ( $filters as $filter_name => $filter_value ) {
    341                                         if ( isset( $friendship->{$filter_name} ) && $filter_value == $friendship->{$filter_name} ) {
     352                                        if ( isset( $friendship->{$filter_name} ) && $filter_value === $friendship->{$filter_name} ) {
    342353                                                $matched++;
    343354                                        }
    344355                                }
    345356
    346                                 if ( ( 'OR' == $operator && $matched > 0 )
    347                                   || ( 'NOT' == $operator && 0 == $matched ) ) {
     357                                if ( ( 'OR' === $operator && $matched > 0 )
     358                                  || ( 'NOT' === $operator && 0 === $matched ) ) {
    348359                                        $friendships[ $friendship->id ] = $friendship;
    349360                                }
     
    355366                                 */
    356367                                foreach ( $filters as $filter_name => $filter_value ) {
    357                                         if ( ! isset( $friendship->{$filter_name} ) || $filter_value != $friendship->{$filter_name} ) {
     368                                        if ( ! isset( $friendship->{$filter_name} ) || $filter_value !== $friendship->{$filter_name} ) {
    358369                                                continue 2;
    359370                                        }
     
    432443
    433444                $friendships = self::get_friendships( $user_id, $args );
     445                $user_id     = (int) $user_id;
    434446
    435447                $fids = array();
    436448                foreach ( $friendships as $friendship ) {
     449                        $friend_id = $friendship->friend_user_id;
     450                        if ( $friendship->friend_user_id === $user_id ) {
     451                                $friend_id = $friendship->initiator_user_id;
     452                        }
     453
    437454                        if ( ! empty( $assoc_arr ) ) {
    438                                 $fids[] = array( 'user_id' => ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id );
     455                                $fids[] = array( 'user_id' => $friend_id );
    439456                        } else {
    440                                 $fids[] = ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id;
     457                                $fids[] = $friend_id;
    441458                        }
    442459                }
     
    637654
    638655                // Can't friend yourself.
    639                 if ( $initiator_userid === $possible_friend_userid ) {
     656                if ( (int) $initiator_userid === (int) $possible_friend_userid ) {
    640657                        return 'not_friends';
    641658                }
     
    663680
    664681                $bp                  = buddypress();
     682                $user_id             = (int) $user_id;
    665683                $possible_friend_ids = wp_parse_id_list( $possible_friend_ids );
    666684
     
    940958                $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 );
    941959                $results = $wpdb->get_results( $sql );
     960                $user_id = (int) $user_id;
    942961
    943962                for ( $i = 0, $count = count( $results ); $i < $count; ++$i ) {
    944                         $fids[] = ( $results[ $i ]->friend_user_id === $user_id ) ? $results[ $i ]->initiator_user_id : $results[ $i ]->friend_user_id;
     963                        $friend_user_id    = (int) $results[ $i ]->friend_user_id;
     964                        $initiator_user_id = (int) $results[ $i ]->initiator_user_id;
     965
     966                        if ( $friend_user_id === $user_id ) {
     967                                $fids[] = $initiator_user_id;
     968                        } else {
     969                                $fids[] = $friend_user_id;
     970                        }
    945971                }
    946972
     
    10591085                global $wpdb;
    10601086
    1061                 $bp = buddypress();
     1087                $bp      = buddypress();
     1088                $user_id = (int) $user_id;
    10621089
    10631090                // Get all friendships, of any status, for the user.
     
    10681095                        $friendship_ids[] = $friendship->id;
    10691096                        if ( $friendship->is_confirmed ) {
    1070                                 $friend_ids[] = ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id;
     1097                                if ( $friendship->friend_user_id === $user_id ) {
     1098                                        $friend_ids[] = $friendship->initiator_user_id;
     1099                                } else {
     1100                                        $friend_ids[] = $friendship->friend_user_id;
     1101                                }
    10711102                        }
    10721103                }
  • branches/10.0/tests/phpunit/testcases/friends/class-bp-friends-friendship.php

    r13086 r13428  
    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.