Skip to:
Content

BuddyPress.org

Changeset 7806


Ignore:
Timestamp:
02/06/2014 01:39:48 AM (10 years ago)
Author:
boonebgorges
Message:

Implement persistent caching in BP_XProfile_ProfileData::get_value_byid()

This change should mean significant performance improvements, as the method
is used a number of places throughout BuddyPress:

  • bp_get_the_profile_field_options() (to check/select the saved values)
  • xprofile_get_field_data()
  • when swapping out blog commenter names with BP display names

Introduces unit tests for the method.

See #1332

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-xprofile/bp-xprofile-classes.php

    r7805 r7806  
    13341334    }
    13351335
     1336    /**
     1337     * Get profile field values by field ID and user IDs.
     1338     *
     1339     * Supports multiple user IDs.
     1340     *
     1341     * @param int $field_id ID of the field.
     1342     * @param int|array $user_ids ID or IDs of user(s).
     1343     * @return string|array Single value if a single user is queried,
     1344     *         otherwise an array of results.
     1345     */
    13361346    public static function get_value_byid( $field_id, $user_ids = null ) {
    13371347        global $wpdb, $bp;
    13381348
    1339         if ( empty( $user_ids ) )
     1349        if ( empty( $user_ids ) ) {
    13401350            $user_ids = bp_displayed_user_id();
    1341 
    1342         if ( is_array( $user_ids ) ) {
    1343             $user_ids = implode( ',', wp_parse_id_list( $user_ids ) );
    1344             $data = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, value FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id IN ({$user_ids})", $field_id ) );
    1345         } else {
    1346             $data = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_ids ) );
    1347         }
    1348 
    1349         return $data;
     1351        }
     1352
     1353        $is_single = false;
     1354        if ( ! is_array( $user_ids ) ) {
     1355            $user_ids  = array( $user_ids );
     1356            $is_single = true;
     1357        }
     1358
     1359        // Assemble uncached IDs
     1360        $uncached_ids = array();
     1361        foreach ( $user_ids as $user_id ) {
     1362            if ( false === wp_cache_get( $field_id, 'bp_xprofile_data_' . $user_id ) ) {
     1363                $uncached_ids[] = $user_id;
     1364            }
     1365        }
     1366
     1367        // Prime caches
     1368        if ( ! empty( $uncached_ids ) ) {
     1369            $uncached_ids_sql = implode( ',', $uncached_ids );
     1370            $queried_data = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, field_id, value, last_updated FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id IN ({$uncached_ids_sql})", $field_id ) );
     1371
     1372            foreach ( $queried_data as $d ) {
     1373                wp_cache_set( $field_id, $d, 'bp_xprofile_data_' . $d->user_id );
     1374            }
     1375        }
     1376
     1377        // Now that the cache is primed with all data, fetch it
     1378        $data = array();
     1379        foreach ( $user_ids as $user_id ) {
     1380            $data[] = wp_cache_get( $field_id, 'bp_xprofile_data_' . $user_id );
     1381        }
     1382
     1383        // If a single ID was passed, just return the value
     1384        if ( $is_single ) {
     1385            return $data[0]->value;
     1386
     1387        // Otherwise return the whole array
     1388        } else {
     1389            return $data;
     1390        }
    13501391    }
    13511392
  • trunk/tests/testcases/xprofile/class-bp-xprofile-profiledata.php

    r7805 r7806  
    118118        $this->assertSame( 5, BP_XProfile_ProfileData::get_fielddataid_byid( $f->id, $u ) );
    119119    }
     120
     121    /**
     122     * @group get_value_byid
     123     */
     124    public function test_get_value_byid_singleuser_uncached() {
     125        $u = $this->create_user();
     126        $g = $this->factory->xprofile_group->create();
     127        $f = $this->factory->xprofile_field->create( array(
     128            'type' => 'textbox',
     129            'field_group_id' => $g->id,
     130        ) );
     131
     132        $d = new BP_XProfile_ProfileData();
     133        $d->user_id = $u;
     134        $d->field_id = $f->id;
     135        $d->value = 'foo';
     136        $d->save();
     137
     138        // Ensure it's deleted from cache
     139        wp_cache_delete( $f->id, 'bp_xprofile_data_' . $u );
     140
     141        $this->assertSame( 'foo', BP_XProfile_ProfileData::get_value_byid( $f->id, $u ) );
     142    }
     143
     144    /**
     145     * @group get_value_byid
     146     */
     147    public function test_get_value_byid_multipleusers_uncached() {
     148        $u1 = $this->create_user();
     149        $u2 = $this->create_user();
     150        $g = $this->factory->xprofile_group->create();
     151        $f = $this->factory->xprofile_field->create( array(
     152            'type' => 'textbox',
     153            'field_group_id' => $g->id,
     154        ) );
     155
     156        $time = bp_core_current_time();
     157
     158        $d1 = new BP_XProfile_ProfileData();
     159        $d1->user_id = $u1;
     160        $d1->field_id = $f->id;
     161        $d1->value = 'foo';
     162        $d1->last_updated = $time;
     163        $d1->save();
     164
     165        $d2 = new BP_XProfile_ProfileData();
     166        $d2->user_id = $u2;
     167        $d2->field_id = $f->id;
     168        $d2->value = 'bar';
     169        $d2->last_updated = $time;
     170        $d2->save();
     171
     172        // Ensure it's deleted from cache
     173        wp_cache_delete( $f->id, 'bp_xprofile_data_' . $u1 );
     174        wp_cache_delete( $f->id, 'bp_xprofile_data_' . $u2 );
     175
     176        $eu1 = new stdClass;
     177        $eu1->user_id = $u1;
     178        $eu1->value = 'foo';
     179        $eu1->id = $d1->id;
     180        $eu1->field_id = $f->id;
     181        $eu1->last_updated = $time;
     182
     183        $eu2 = new stdClass;
     184        $eu2->user_id = $u2;
     185        $eu2->value = 'bar';
     186        $eu2->id = $d2->id;
     187        $eu2->field_id = $f->id;
     188        $eu2->last_updated = $time;
     189
     190        $expected = array( $eu1, $eu2 );
     191
     192        $this->assertEquals( $expected, BP_XProfile_ProfileData::get_value_byid( $f->id, array( $u1, $u2 ) ) );
     193    }
     194
     195    /**
     196     * @group get_value_byid
     197     */
     198    public function test_get_value_byid_singleuser_cached() {
     199        $u = $this->create_user();
     200        $g = $this->factory->xprofile_group->create();
     201        $f = $this->factory->xprofile_field->create( array(
     202            'type' => 'textbox',
     203            'field_group_id' => $g->id,
     204        ) );
     205
     206        $time = bp_core_current_time();
     207
     208        // Fake the cache
     209        $d = new stdClass;
     210        $d->value = 'foo';
     211        $d->field_id = $f->id;
     212        wp_cache_set( $f->id, $d, 'bp_xprofile_data_' . $u );
     213
     214        $this->assertSame( 'foo', BP_XProfile_ProfileData::get_value_byid( $f->id, $u ) );
     215    }
     216
     217    /**
     218     * @group get_value_byid
     219     */
     220    public function test_get_value_byid_multipleusers_cached() {
     221        $u1 = $this->create_user();
     222        $u2 = $this->create_user();
     223        $g = $this->factory->xprofile_group->create();
     224        $f = $this->factory->xprofile_field->create( array(
     225            'type' => 'textbox',
     226            'field_group_id' => $g->id,
     227        ) );
     228
     229        // Fake the cache
     230        $d1 = new stdClass;
     231        $d1->id = 10;
     232        $d1->user_id = $u1;
     233        $d1->field_id = $f->id;
     234        $d1->value = 'foo';
     235        $d1->last_updated = $time;
     236
     237        $d2 = new stdClass;
     238        $d1->id = 21;
     239        $d2->user_id = $u2;
     240        $d2->field_id = $f->id;
     241        $d2->value = 'bar';
     242        $d2->last_updated = $time;
     243
     244        wp_cache_set( $f->id, $d1, 'bp_xprofile_data_' . $u1 );
     245        wp_cache_set( $f->id, $d2, 'bp_xprofile_data_' . $u2 );
     246
     247        $eu1 = new stdClass;
     248        $eu1->id = 10;
     249        $eu1->user_id = $u1;
     250        $eu1->field_id = $f->id;
     251        $eu1->value = 'foo';
     252        $eu1->last_updated = $time;
     253
     254        $eu2 = new stdClass;
     255        $eu1->id = 21;
     256        $eu2->user_id = $u2;
     257        $eu2->field_id = $f->id;
     258        $eu2->value = 'bar';
     259        $eu2->last_updated = $time;
     260
     261        $expected = array( $eu1, $eu2 );
     262
     263        $this->assertEquals( $expected, BP_XProfile_ProfileData::get_value_byid( $f->id, array( $u1, $u2 ) ) );
     264    }
     265
    120266}
Note: See TracChangeset for help on using the changeset viewer.