WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The situation

Running on MU, I'm writing an open source/publically and freely available plugin. As I used add_screen_option() to allow users to easily setup the admin page to their likings, I'm left with a bunch of user meta data. Now the page itself is restricted to users with the manage_options capability, so only those have got this meta entry when they adjusted the per page value for a list table.

The "per page" Screen Option

The task

To allow the plugin to leave a clean state in case some chooses to remove the plugin, I added a deactivation and an uninstall hook callback that should loop through user data and remove the meta entries. Now I could simply loop through all users, check their meta value and so on, but this would hardly fail on sites with lots of users and end in a time out (remember, Meta tables are JOINed).

The idea (so far)

To make it short, here's what I thought: The MU install has a user and a usermeta table. And from what I can see, there're not really capabilities saved, but role names - WordPress makes no difference between roles and capabilities here. Fun as it is, it seems that there're different things I have to consider:

User can be…

  • superadmin
  • registered on multiple sites
  • registered on multiple sites with different roles
  • registered on multiple sites with the same role, but role has different capabilities on different sites
  • ...?

The problem starts with those different possibilities and goes further, when you look at ho the capabilities are saved in a Network/MU setup:




So for what would one query?

$query_args = array(
$query = new WP_User_Query( $query_args );
$users = $query->results;
if ( empty( $users ) )

var_dump( $users );


Just a first attempt to query for role names with a specific capability:

    $roles = new WP_Roles();
    $roles = wp_list_pluck( $roles->role_objects, 'capabilities' );
    $results = array();
    foreach ( $roles as $role => $caps )
        array_key_exists( 'manage_options', $caps )
            AND $results[] = $role;
    var_dump( $results );

    # Even if it's smarter then above loop, it won't work and 
    # throw an error in core files.
    $roles = array_filter( wp_list_pluck( $roles, 'manage_options' ) );
share|improve this question
up vote 1 down vote accepted

It was actually much easier than I originally thought - just doing a WP_User_Query for a meta value (meta arrays are supported as well, like for the other query classes).

public function on_deactivate()
    $meta_key = 'tools_page_tsi_per_page';
    $query = new WP_User_Query( array( 'meta_key' => $meta_key ) );

    if ( empty( $query->results ) )

    foreach ( wp_list_pluck( $query->results, 'ID' ) as $user_id )
        delete_user_meta( $user_id, $meta_key );
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.