Per user, per site Dashboard and Screen Options in WordPress multisite

By on Jun 6th

The Offbeat Empire uses many plugins on our sites to streamline the writing and editing process. Different users have access to different plugins, depending on their job. When editors began reporting that their plugin settings were not sticking on the Add New Post page, I dug into the code and found that WordPress (as of version 3.2) was overwriting their Screen Options settings every time they visited the Add New Post page, no matter which blog they visited. For example, if they regularly used the Editorial Comments meta box on one blog and had moved it to be directly under the main post box, this preference in their Add New Post layout would be overwritten if they visited the Dashboard of a blog without the Editorial Comments plugin.

I ended up writing the following functions that create a series of shadow screen options for each user. This code filters reads and writes of user Screen Options metadata based on the blog_id global variable. Screen Options for plugin-generated meta boxes will be saved on a per site basis for each user, allowing them to retain their Add New/Edit Post appearance on each separate blog.

This code is useful on multisite installs with a finite number of users and blogs where blogs have different uses and the active plugin set differs between blogs.

function ucc_sso_update_user_metadata( $meta_type = null, $user_id, $meta_key, $meta_value, $prev_value = '' ) {
  global $blog_id, $wpdb;

  $prefix = 'ucc_sso_' . $blog_id . '_';
  if ( preg_match( "#^closedpostboxes#", $meta_key ) ||
       preg_match( "#^metaboxhidden#", $meta_key ) ||
       preg_match( "#^meta-box-order#", $meta_key ) ||
       preg_match( "#^screen_layout#", $meta_key ) ) {
    $meta_key = $prefix . $meta_key;
    $result = update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' );
    return $result;
  } else {
    return null;
  }
}
add_filter( 'update_user_metadata', 'ucc_sso_update_user_metadata', 10, 5 );

function ucc_sso_get_user_metadata( $meta_type = null, $user_id, $meta_key, $single ) {
  global $blog_id, $wpdb;

  $prefix = 'ucc_sso_' . $blog_id . '_';
  if ( preg_match( "#^closedpostboxes#", $meta_key ) ||
       preg_match( "#^metaboxhidden#", $meta_key ) ||
       preg_match( "#^meta-box-order#", $meta_key ) ||
       preg_match( "#^screen_layout#", $meta_key ) ) {
    $meta_key = $prefix . $meta_key;
    $result = get_user_meta( $user_id, $meta_key, $single );
    return $result;
  } else {
    return null;
  }
}
add_filter( 'get_user_metadata', 'ucc_sso_get_user_metadata', 10, 4 );

function ucc_sso_get_user_option( $result, $option, $user ) {
  global $blog_id, $wpdb;

  $prefix = 'ucc_sso_' . $blog_id . '_';
  $option = $prefix . $option;
  $result = get_user_option( $option, $user->ID );

  return $result;
}
add_filter( "get_user_option_closedpostboxes_post", 'ucc_sso_get_user_option', 10, 3 );
add_filter( "get_user_option_metaboxhidden_post", 'ucc_sso_get_user_option', 10, 3 );
add_filter( "get_user_option_meta-box-order_post", 'ucc_sso_get_user_option', 10, 3 );
add_filter( "get_user_option_screen_layout_post", 'ucc_sso_get_user_option', 10, 3 );

Code contained in this entry is licensed under GNU General Public License, version 2.

References

Read more posts about: , , ,