Skip to:
Content

BuddyPress.org

Ticket #6211: 6211.diff

File 6211.diff, 8.1 KB (added by boonebgorges, 5 years ago)
  • src/bp-xprofile/bp-xprofile-functions.php

    diff --git src/bp-xprofile/bp-xprofile-functions.php src/bp-xprofile/bp-xprofile-functions.php
    index 16c1599..a0fd655 100644
    function bp_xprofile_bp_user_query_search( $sql, BP_User_Query $query ) { 
    738738                $search_terms_space   = '%' . $search_terms_clean . '%';
    739739        }
    740740
    741         // Combine the core search (against wp_users) into a single OR clause
    742         // with the xprofile_data search
    743         $search_xprofile = $wpdb->prepare(
    744                 "u.{$query->uid_name} IN ( SELECT user_id FROM {$bp->profile->table_name_data} WHERE value LIKE %s OR value LIKE %s )",
     741        // Do a separate search, and then filter results based on field visibility levels.
     742        $xprofile_matches = $wpdb->get_results( $wpdb->prepare(
     743                "SELECT user_id, field_id FROM {$bp->profile->table_name_data} WHERE value LIKE %s OR value LIKE %s",
    745744                $search_terms_nospace,
    746745                $search_terms_space
    747         );
     746        ) );
     747
     748        $raw_levels = array( 'public' );
     749
     750        if ( is_user_logged_in() ) {
     751                $raw_levels[] = 'loggedin';
     752        }
     753
     754        if ( bp_current_user_can( 'bp_moderate' ) ) {
     755                $raw_levels[] = 'adminsonly';
     756        }
     757
     758        $user_friend_ids = array();
     759        if ( bp_is_active( 'friends' ) && is_user_logged_in() ) {
     760                $user_friend_ids = friends_get_friend_user_ids( bp_loggedin_user_id() );
     761        }
    748762
    749         $search_core     = $sql['where']['search'];
    750         $search_combined = "( {$search_xprofile} OR {$search_core} )";
    751         $sql['where']['search'] = $search_combined;
     763        // Loop through and exclude any fields the current user doesn't have access to.
     764        // @todo Make this not terrible.
     765        foreach ( $xprofile_matches as $xmk => $xprofile_match ) {
     766                // Always show yourself.
     767                if ( is_user_logged_in() && bp_loggedin_user_id() == $xprofile_match->user_id ) {
     768                        continue;
     769                }
     770
     771                $levels = $raw_levels;
     772                if ( in_array( $xprofile_match->user_id, $user_friend_ids ) ) {
     773                        $levels[] = 'friends';
     774                }
     775
     776                $user_fields = bp_xprofile_get_fields_by_visibility_levels( $xprofile_match->user_id, $levels );
     777                if ( ! in_array( $xprofile_match->field_id, $user_fields ) ) {
     778                        unset( $xprofile_matches[ $xmk ] );
     779                }
     780        }
     781
     782        // Any remaining profile matches should be visible, so we add a simple IN clause to the main query.
     783        if ( ! empty( $xprofile_matches ) ) {
     784                $cleared_user_ids = implode( ',', wp_parse_id_list( wp_list_pluck( $xprofile_matches, 'user_id' ) ) );
     785                $search_xprofile = "u.{$query->uid_name} IN ($cleared_user_ids)";
     786
     787                $search_core     = $sql['where']['search'];
     788                $search_combined = "( {$search_xprofile} OR {$search_core} )";
     789                $sql['where']['search'] = $search_combined;
     790        }
    752791
    753792        return $sql;
    754793}
  • tests/phpunit/testcases/core/class-bp-user-query.php

    diff --git tests/phpunit/testcases/core/class-bp-user-query.php tests/phpunit/testcases/core/class-bp-user-query.php
    index 18fe71a..e25147d 100644
    class BP_Tests_BP_User_Query_TestCases extends BP_UnitTestCase { 
    271271        }
    272272
    273273        /**
     274         * @group xprofile
     275         * @group BP6211
     276         */
     277        public function test_search_should_ignore_loggedin_fields_for_non_loggedin_user() {
     278                if ( ! bp_is_active( 'xprofile' ) ) {
     279                        $this->markTestSkipped( 'xprofile is required for this test' );
     280                }
     281
     282                $users = $this->factory->user->create_many( 2 );
     283                $g = $this->factory->xprofile_group->create();
     284                $f = $this->factory->xprofile_field->create( array(
     285                        'field_group_id' => $g,
     286                        'type' => 'textbox',
     287                ) );
     288
     289                xprofile_set_field_visibility_level( $f, $users[0], 'loggedin' );
     290                xprofile_set_field_visibility_level( $f, $users[1], 'public' );
     291                xprofile_set_field_data( $f, $users[0], 'foo bar baz' );
     292                xprofile_set_field_data( $f, $users[1], 'foo bar baz' );
     293
     294                $old_user = get_current_user_id();
     295                $this->set_current_user( 0 );
     296
     297                $q = new BP_User_Query( array(
     298                        'search_terms' => 'bar',
     299                ) );
     300
     301                $this->set_current_user( $old_user );
     302
     303                $this->assertEqualSets( array( $users[1] ), wp_list_pluck( $q->results, 'ID' ) );
     304        }
     305
     306        /**
     307         * @group xprofile
     308         * @group BP6211
     309         */
     310        public function test_search_should_ignore_adminsonly_fields_for_non_admin_user() {
     311                if ( ! bp_is_active( 'xprofile' ) ) {
     312                        $this->markTestSkipped( 'xprofile is required for this test' );
     313                }
     314
     315                $users = $this->factory->user->create_many( 3 );
     316                $g = $this->factory->xprofile_group->create();
     317                $f = $this->factory->xprofile_field->create( array(
     318                        'field_group_id' => $g,
     319                        'type' => 'textbox',
     320                ) );
     321
     322                xprofile_set_field_visibility_level( $f, $users[0], 'adminsonly' );
     323                xprofile_set_field_visibility_level( $f, $users[1], 'public' );
     324                xprofile_set_field_data( $f, $users[0], 'foo bar baz' );
     325                xprofile_set_field_data( $f, $users[1], 'foo bar baz' );
     326
     327                $old_user = get_current_user_id();
     328                $this->set_current_user( $users[2] );
     329
     330                $q = new BP_User_Query( array(
     331                        'search_terms' => 'bar',
     332                ) );
     333
     334                $this->set_current_user( $old_user );
     335
     336                $this->assertEqualSets( array( $users[1] ), wp_list_pluck( $q->results, 'ID' ) );
     337        }
     338
     339        /**
     340         * @group xprofile
     341         * @group BP6211
     342         */
     343        public function test_search_should_show_adminsonly_fields_for_admin_user() {
     344                if ( ! bp_is_active( 'xprofile' ) ) {
     345                        $this->markTestSkipped( 'xprofile is required for this test' );
     346                }
     347
     348                $users = $this->factory->user->create_many( 3 );
     349                $g = $this->factory->xprofile_group->create();
     350                $f = $this->factory->xprofile_field->create( array(
     351                        'field_group_id' => $g,
     352                        'type' => 'textbox',
     353                ) );
     354
     355                xprofile_set_field_visibility_level( $f, $users[0], 'adminsonly' );
     356                xprofile_set_field_visibility_level( $f, $users[1], 'public' );
     357                xprofile_set_field_data( $f, $users[0], 'foo bar baz' );
     358                xprofile_set_field_data( $f, $users[1], 'foo bar baz' );
     359
     360                $old_user = get_current_user_id();
     361                $this->grant_bp_moderate( $users[2] );
     362                $this->set_current_user( $users[2] );
     363                $q = new BP_User_Query( array(
     364                        'search_terms' => 'bar',
     365                ) );
     366
     367                $this->revoke_bp_moderate( $users[2] );
     368                $this->set_current_user( $old_user );
     369
     370                $this->assertEqualSets( array( $users[0], $users[1] ), wp_list_pluck( $q->results, 'ID' ) );
     371        }
     372
     373        /**
     374         * @group xprofile
     375         * @group BP6211
     376         */
     377        public function test_search_should_show_adminsonly_fields_for_self() {
     378                if ( ! bp_is_active( 'xprofile' ) ) {
     379                        $this->markTestSkipped( 'xprofile is required for this test' );
     380                }
     381
     382                $users = $this->factory->user->create_many( 2 );
     383                $g = $this->factory->xprofile_group->create();
     384                $f = $this->factory->xprofile_field->create( array(
     385                        'field_group_id' => $g,
     386                        'type' => 'textbox',
     387                ) );
     388
     389                xprofile_set_field_visibility_level( $f, $users[0], 'adminsonly' );
     390                xprofile_set_field_visibility_level( $f, $users[1], 'adminsonly' );
     391                xprofile_set_field_data( $f, $users[0], 'foo bar baz' );
     392                xprofile_set_field_data( $f, $users[1], 'foo bar baz' );
     393
     394                $old_user = get_current_user_id();
     395                $this->set_current_user( $users[1] );
     396
     397                $q = new BP_User_Query( array(
     398                        'search_terms' => 'bar',
     399                ) );
     400
     401                $this->set_current_user( $old_user );
     402
     403                $this->assertEqualSets( array( $users[1] ), wp_list_pluck( $q->results, 'ID' ) );
     404        }
     405
     406        /**
     407         * @group xprofile
     408         * @group BP6211
     409         */
     410        public function test_search_should_ignore_friends_fields_for_non_friends() {
     411                if ( ! bp_is_active( 'xprofile' ) ) {
     412                        $this->markTestSkipped( 'xprofile is required for this test' );
     413                }
     414
     415                $users = $this->factory->user->create_many( 3 );
     416                $g = $this->factory->xprofile_group->create();
     417                $f = $this->factory->xprofile_field->create( array(
     418                        'field_group_id' => $g,
     419                        'type' => 'textbox',
     420                ) );
     421
     422                xprofile_set_field_visibility_level( $f, $users[0], 'friends' );
     423                xprofile_set_field_visibility_level( $f, $users[1], 'friends' );
     424                xprofile_set_field_data( $f, $users[0], 'foo bar baz' );
     425                xprofile_set_field_data( $f, $users[1], 'foo bar baz' );
     426
     427                $old_user = get_current_user_id();
     428                $this->set_current_user( $users[2] );
     429                friends_add_friend( $users[1], $users[2], true );
     430
     431                $q = new BP_User_Query( array(
     432                        'search_terms' => 'bar',
     433                ) );
     434
     435                $this->set_current_user( $old_user );
     436
     437                $this->assertEqualSets( array( $users[1] ), wp_list_pluck( $q->results, 'ID' ) );
     438        }
     439
     440        /**
    274441         * @group exclude
    275442         */
    276443        public function test_bp_user_query_with_exclude() {