Skip to:
Content

BuddyPress.org

Changeset 8315


Ignore:
Timestamp:
04/24/2014 12:22:29 AM (10 years ago)
Author:
boonebgorges
Message:

Improve the migration tool that converts old non-multisite signups to post-2.0 system

This refactoring involves a number of improvements:

  • Old signups are identified as those users with user_status=2, instead of those users with an 'activation_key' usermeta value. Use of the latter technique caused problems with upgrades when plugins had interfered in the normal BuddyPress registration flow in such a way as to retain the activation key on activated accounts. user_status=2 is a more reliable technique.
  • Querying by user_status=2 means that the get_users() query does not have to include all usermeta, which makes for a more performant query on large sites.
  • The migration routine has been broken out into a separate function bp_members_migrate_signups(), and unit tests have been written for it.
  • Activation keys are now regenerated for migrated users who did not have an existing key in usermeta for some reason.

Fixes #5553

Props imath

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-core/bp-core-update.php

    r8313 r8315  
    366366        bp_core_maybe_install_signups();
    367367
    368         $signups = get_users( array(
    369             'fields'       => 'all_with_meta',
    370             'meta_key'     => 'activation_key',
    371             'meta_compare' => 'EXISTS',
    372         ) );
    373 
    374         if ( empty( $signups ) ) {
    375             return;
    376         }
    377 
    378         foreach ( $signups as $signup ) {
    379             $meta = array();
    380 
    381             if ( bp_is_active( 'xprofile' ) ) {
    382                 $meta['field_1'] = $signup->display_name;
    383             }
    384 
    385             $meta['password'] = $signup->user_pass;
    386 
    387             $user_login = preg_replace( '/\s+/', '', sanitize_user( $signup->user_login, true ) );
    388             $user_email = sanitize_email( $signup->user_email );
    389 
    390             BP_Signup::add( array(
    391                 'user_login'     => $user_login,
    392                 'user_email'     => $user_email,
    393                 'registered'     => $signup->user_registered,
    394                 'activation_key' => $signup->activation_key,
    395                 'meta'           => $meta
    396             ) );
    397 
    398             // Deleting these options will remove signups from users count
    399             delete_user_option( $signup->ID, 'capabilities' );
    400             delete_user_option( $signup->ID, 'user_level'   );
    401         }
     368        // Run the migration script
     369        bp_members_migrate_signups();
    402370    }
    403371
  • trunk/bp-members/bp-members-functions.php

    r8272 r8315  
    16381638}
    16391639
     1640/**
     1641 * Migrate signups from pre-2.0 configuration to wp_signups.
     1642 *
     1643 * @since BuddyPress (2.0.1)
     1644 */
     1645function bp_members_migrate_signups() {
     1646    global $wpdb;
     1647
     1648    $status_2_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->users} WHERE user_status = '2'" );
     1649
     1650    if ( ! empty( $status_2_ids ) ) {
     1651        $signups = get_users( array(
     1652            'fields'  => array(
     1653                'ID',
     1654                'user_login',
     1655                'user_pass',
     1656                'user_registered',
     1657                'user_email',
     1658                'display_name',
     1659            ),
     1660            'include' => $status_2_ids,
     1661        ) );
     1662
     1663        // Fetch activation keys separately, to avoid the all_with_meta
     1664        // overhead
     1665        $status_2_ids_sql = implode( ',', $status_2_ids );
     1666        $ak_data = $wpdb->get_results( "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = 'activation_key' AND user_id IN ({$status_2_ids_sql})" );
     1667
     1668        // Rekey
     1669        $activation_keys = array();
     1670        foreach ( $ak_data as $ak_datum ) {
     1671            $activation_keys[ intval( $ak_datum->user_id ) ] = $ak_datum->meta_value;
     1672        }
     1673
     1674        unset( $status_2_ids_sql, $status_2_ids, $ak_data );
     1675
     1676        // Merge
     1677        foreach ( $signups as &$signup ) {
     1678            if ( isset( $activation_keys[ $signup->ID ] ) ) {
     1679                $signup->activation_key = $activation_keys[ $signup->ID ];
     1680            }
     1681        }
     1682
     1683        // Reset the signup var as we're using it to process the migration
     1684        unset( $signup );
     1685
     1686    } else {
     1687        return;
     1688    }
     1689
     1690    foreach ( $signups as $signup ) {
     1691        $meta = array();
     1692
     1693        // Rebuild the activation key, if missing
     1694        if ( empty( $signup->activation_key ) ) {
     1695            $signup->activation_key = wp_hash( $signup->ID );
     1696        }
     1697
     1698        if ( bp_is_active( 'xprofile' ) ) {
     1699            $meta['field_1'] = $signup->display_name;
     1700        }
     1701
     1702        $meta['password'] = $signup->user_pass;
     1703
     1704        $user_login = preg_replace( '/\s+/', '', sanitize_user( $signup->user_login, true ) );
     1705        $user_email = sanitize_email( $signup->user_email );
     1706
     1707        BP_Signup::add( array(
     1708            'user_login'     => $user_login,
     1709            'user_email'     => $user_email,
     1710            'registered'     => $signup->user_registered,
     1711            'activation_key' => $signup->activation_key,
     1712            'meta'           => $meta
     1713        ) );
     1714
     1715        // Deleting these options will remove signups from users count
     1716        delete_user_option( $signup->ID, 'capabilities' );
     1717        delete_user_option( $signup->ID, 'user_level'   );
     1718    }
     1719}
     1720
    16401721function bp_core_new_user_activity( $user ) {
    16411722    if ( empty( $user ) || !bp_is_active( 'activity' ) )
  • trunk/tests/testcases/members/functions.php

    r8027 r8315  
    280280        $this->assertSame( $expected, bp_core_get_user_displaynames( array( $u1, $u2, ) ) );
    281281    }
     282
     283    /**
     284     * @group bp_members_migrate_signups
     285     */
     286    public function test_bp_members_migrate_signups_standard() {
     287        $u = $this->create_user();
     288        $u_obj = new WP_User( $u );
     289
     290        // Fake an old-style registration
     291        $key = wp_hash( $u_obj->ID );
     292        update_user_meta( $u, 'activation_key', $key );
     293
     294        global $wpdb;
     295        $wpdb->update(
     296            $wpdb->users,
     297            array( 'user_status' => '2', ),
     298            array( 'ID' => $u, ),
     299            array( '%d', ),
     300            array( '%d', )
     301        );
     302        clean_user_cache( $u );
     303
     304        bp_members_migrate_signups();
     305
     306        $found = BP_Signup::get();
     307
     308        // Use email address as a sanity check
     309        $found_email = isset( $found['signups'][0]->user_email ) ? $found['signups'][0]->user_email : '';
     310        $this->assertSame( $u_obj->user_email, $found_email );
     311
     312        // Check that activation keys match
     313        $found_key = isset( $found['signups'][0]->activation_key ) ? $found['signups'][0]->activation_key : '';
     314        $this->assertSame( $key, $found_key );
     315    }
     316
     317    /**
     318     * @group bp_members_migrate_signups
     319     */
     320    public function test_bp_members_migrate_signups_activation_key_but_user_status_0() {
     321        $u = $this->create_user();
     322        $u_obj = new WP_User( $u );
     323
     324        // Fake an old-style registration
     325        $key = wp_hash( $u_obj->ID );
     326        update_user_meta( $u, 'activation_key', $key );
     327
     328        // ...but ensure that user_status is 0. This mimics the
     329        // behavior of certain plugins that disrupt the BP registration
     330        // flow
     331        global $wpdb;
     332        $wpdb->update(
     333            $wpdb->users,
     334            array( 'user_status' => '0', ),
     335            array( 'ID' => $u, ),
     336            array( '%d', ),
     337            array( '%d', )
     338        );
     339        clean_user_cache( $u );
     340
     341        bp_members_migrate_signups();
     342
     343        // No migrations should have taken place
     344        $found = BP_Signup::get();
     345        $this->assertEmpty( $found['total'] );
     346    }
     347
     348    /**
     349     * @group bp_members_migrate_signups
     350     */
     351    public function test_bp_members_migrate_signups_no_activation_key_but_user_status_2() {
     352        $u = $this->create_user();
     353        $u_obj = new WP_User( $u );
     354
     355        // Fake an old-style registration but without an activation key
     356        global $wpdb;
     357        $wpdb->update(
     358            $wpdb->users,
     359            array( 'user_status' => '2', ),
     360            array( 'ID' => $u, ),
     361            array( '%d', ),
     362            array( '%d', )
     363        );
     364        clean_user_cache( $u );
     365
     366        bp_members_migrate_signups();
     367
     368        // Use email address as a sanity check
     369        $found = BP_Signup::get();
     370        $found_email = isset( $found['signups'][0]->user_email ) ? $found['signups'][0]->user_email : '';
     371        $this->assertSame( $u_obj->user_email, $found_email );
     372    }
    282373}
Note: See TracChangeset for help on using the changeset viewer.