Programatically Changing Users’ Roles in WordPress Multisite


Background:
I inherited three different WordPress installations (each one on a separate closed network) from a developer that was leaving our contract for a government civilian position.  I had a grand total of five days to pick his brain about WordPress, and our infrastructure.  It sucked, greatly.
We had two custom Roles in our installations: Blog Owner, and Team Admin.  Blog Owner (listed as ‘owner’ in the database) was the role assigned to the Administrator of a personal blog (a blog with only one user, and said user was the administrator).  Team Admin (listed as ‘teamadmin’ in the database) was the role assigned to users that were Administrators for a “Team Blog”, basically a blog with multiple user accounts associated to it.  Why did we go this way? I have no clue.  I was not part of our organization at that point.
When I upgraded everything to WordPress 3.2.1, Administrators, Blog Owners and Team Admin’s seemed to lose some abilities.  In particular, they did not have the ‘edit_theme_options’, or ‘list_users’ capability.  Upon further research, it seems that I now have two major problems:  The upgrades did not recognize my custom roles, and thereby did not apply the appropriate capabilities to those roles. I looked through the database and saw that I’d have to change over 9,000 records in the wp_usermeta table, on one network alone.
Did I mention that on one network I have over 6,590 blogs, with over 12,000 users?  Yeah, that’s a lot of user editing that I would not do by hand.
Solution:
After much discussion via Twitter, I came up with the following little piece of code that is working for me, and I hope it helps with others.  With regards to the paths, I have this as a php page in a subdirectory of the home directory of our WordPress installation, hence the ‘../’ in each require statement.  Edit that as you need.
global $wpdb;
ini_set("display_errors", "1");
define("WP_INSTALLING", true);
require('../wp-config.php');
require('../wp-blog-header.php');
require('../wp-includes/registration.php');
get_header();
/*
*  Edit this variable to reflect the custom role you want to change.
*/
$role_to_update = 'a:1:{s:5:\"owner\";b:1;}';
$results = $wpdb->get_results("select * from wp_usermeta where meta_value=". $role_to_update .";", ARRAY_A);
if (is_array($results))
{
foreach ($results as $result)
{
//  This line pulls out the blog_id from the meta_key, i.e., 'wp_BLOGID_capabilities'
$blogid = mb_substr($result['meta_key'], strpos($result['meta_key'], '_') +1, strrpos($result['meta_key'], '_') -3 );
$user_id = $result['user_id'];
switch_to_blog($blogid);
$user = new WP_User($user_id);
//  Make sure you have the correct role here that you want to remove.
$user->remove_role('owner');
$user->add_role('administrator');
restore_current_blog();
}
}
echo "DONE!";

This is quick, dirty, and ugly, but it’s working for me. I would LOVE feedback on how to do this better, cleaner and/or more efficient!


One response to “Programatically Changing Users’ Roles in WordPress Multisite”

Leave a Reply

Your email address will not be published. Required fields are marked *