Skip to content

Commit cc8cc8a

Browse files
committed
Upgrade/Install: Reduce number of DB queries populating roles.
Reduces the number of database queries made when populating roles during install/multisite site creation by 344 (347 queries down to 3). `populate_roles()` has been modified to prevent an individual database query each time a role or capability is added to the `WP_Roles` object. Instead the roles option, `{$wpdb->prefix}user_roles` is updated once at the end of the function call. Introduces a test to ensure that updating the roles option via `WP_Roles` and updating the option in the manner now used by `populate_roles()` results in the same capabilities been applied to a role. Props fliespl, johnjamesjacoby, ocean90, realloc, rishabhwp, sainathpoojary, sirlouen, spacedmonkey, swissspidy. Fixes #37687. git-svn-id: https://develop.svn.wordpress.org/trunk@60614 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 7dae010 commit cc8cc8a

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/wp-admin/includes/schema.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,13 @@ function populate_options( array $options = array() ) {
713713
* @since 2.0.0
714714
*/
715715
function populate_roles() {
716+
$wp_roles = wp_roles();
717+
718+
// Disable role updates to the database while populating roles.
719+
$original_use_db = $wp_roles->use_db;
720+
$wp_roles->use_db = false;
721+
722+
// Populate roles
716723
populate_roles_160();
717724
populate_roles_210();
718725
populate_roles_230();
@@ -721,6 +728,14 @@ function populate_roles() {
721728
populate_roles_270();
722729
populate_roles_280();
723730
populate_roles_300();
731+
732+
// Save the updated roles to the database.
733+
if ( $original_use_db ) {
734+
update_option( $wp_roles->role_key, $wp_roles->roles, true );
735+
}
736+
737+
// Restore original value for writing to database.
738+
$wp_roles->use_db = $original_use_db;
724739
}
725740

726741
/**

tests/phpunit/tests/user/capabilities.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,4 +2542,55 @@ public function test_edit_block_binding_caps_are_mapped_correctly() {
25422542
);
25432543
}
25442544
}
2545+
2546+
/**
2547+
* Ensure that caps are updated correctly when using `update_option()` to save roles.
2548+
*
2549+
* Compares the efficiency and accuracy of updating role capabilities when `WP_Roles`
2550+
* uses the database vs when the updates are done via `update_option()`.
2551+
*
2552+
* This method of updating roles is used in `populate_roles()` to reduce the number of
2553+
* queries by approximately 300.
2554+
*
2555+
* @ticket 37687
2556+
*/
2557+
public function test_role_capabilities_updated_correctly_via_update_option() {
2558+
global $wp_roles;
2559+
$emcee_role = 'emcee';
2560+
$wp_roles->add_role( $emcee_role, 'Emcee', array( 'level_1' => true ) );
2561+
$this->flush_roles();
2562+
2563+
$expected_caps = array(
2564+
'level_1' => true,
2565+
'attend_kit_kat_klub' => true,
2566+
'win_tony_award' => true,
2567+
);
2568+
2569+
$start_queries = get_num_queries();
2570+
$wp_roles->add_cap( $emcee_role, 'attend_kit_kat_klub' );
2571+
$wp_roles->add_cap( $emcee_role, 'win_tony_award' );
2572+
$emcee_queries = get_num_queries() - $start_queries;
2573+
$this->flush_roles();
2574+
$emcee_caps = $wp_roles->get_role( $emcee_role )->capabilities;
2575+
2576+
$wp_roles->use_db = false;
2577+
$sally_role = 'sally';
2578+
$wp_roles->add_role( $sally_role, 'Sally Bowles', array( 'level_1' => true ) );
2579+
$start_queries = get_num_queries();
2580+
$wp_roles->add_cap( $sally_role, 'attend_kit_kat_klub' );
2581+
$wp_roles->add_cap( $sally_role, 'win_tony_award' );
2582+
2583+
update_option( $wp_roles->role_key, $wp_roles->roles, true );
2584+
$sally_queries = get_num_queries() - $start_queries;
2585+
$wp_roles->use_db = true;
2586+
2587+
// Restore the default value.
2588+
$this->flush_roles();
2589+
$sally_caps = $wp_roles->get_role( $sally_role )->capabilities;
2590+
2591+
$this->assertSameSetsWithIndex( $expected_caps, $emcee_caps, 'Emcee role should include the three expected capabilities.' );
2592+
$this->assertSameSetsWithIndex( $expected_caps, $sally_caps, 'Sally role should include the three expected capabilities.' );
2593+
$this->assertSameSetsWithIndex( $emcee_caps, $sally_caps, 'Emcee and Sally roles should have the same capabilities after update.' );
2594+
$this->assertLessThan( $emcee_queries, $sally_queries, 'Updating roles via update_option should be more efficient than WP_Roles using the database.' );
2595+
}
25452596
}

0 commit comments

Comments
 (0)