Skip to:
Content

BuddyPress.org

Changeset 7806


Ignore:
Timestamp:
02/06/2014 01:39:48 AM (12 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.