web/wp-includes/capabilities.php
changeset 204 09a1c134465b
parent 194 32102edaa81b
--- a/web/wp-includes/capabilities.php	Wed Dec 19 12:35:13 2012 -0800
+++ b/web/wp-includes/capabilities.php	Wed Dec 19 17:46:52 2012 -0800
@@ -108,7 +108,37 @@
 
 		$this->role_objects = array();
 		$this->role_names =  array();
-		foreach ( (array) $this->roles as $role => $data ) {
+		foreach ( array_keys( $this->roles ) as $role ) {
+			$this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
+			$this->role_names[$role] = $this->roles[$role]['name'];
+		}
+	}
+
+	/**
+	 * Reinitialize the object
+	 *
+	 * Recreates the role objects. This is typically called only by switch_to_blog()
+	 * after switching wpdb to a new blog ID.
+	 *
+	 * @since 3.5.0
+	 * @access public
+	 */
+	function reinit() {
+		// There is no need to reinit if using the wp_user_roles global.
+		if ( ! $this->use_db )
+			return;
+
+		global $wpdb, $wp_user_roles;
+
+		// Duplicated from _init() to avoid an extra function call.
+		$this->role_key = $wpdb->prefix . 'user_roles';
+		$this->roles = get_option( $this->role_key );
+		if ( empty( $this->roles ) )
+			return;
+
+		$this->role_objects = array();
+		$this->role_names =  array();
+		foreach ( array_keys( $this->roles ) as $role ) {
 			$this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
 			$this->role_names[$role] = $this->roles[$role]['name'];
 		}
@@ -176,6 +206,9 @@
 	 * @param bool $grant Optional, default is true. Whether role is capable of performing capability.
 	 */
 	function add_cap( $role, $cap, $grant = true ) {
+		if ( ! isset( $this->roles[$role] ) )
+			return;
+
 		$this->roles[$role]['capabilities'][$cap] = $grant;
 		if ( $this->use_db )
 			update_option( $this->role_key, $this->roles );
@@ -191,6 +224,9 @@
 	 * @param string $cap Capability name.
 	 */
 	function remove_cap( $role, $cap ) {
+		if ( ! isset( $this->roles[$role] ) )
+			return;
+
 		unset( $this->roles[$role]['capabilities'][$cap] );
 		if ( $this->use_db )
 			update_option( $this->role_key, $this->roles );
@@ -233,8 +269,7 @@
 	 * @param string $role Role name to look up.
 	 * @return bool
 	 */
-	function is_role( $role )
-	{
+	function is_role( $role ) {
 		return isset( $this->role_names[$role] );
 	}
 }
@@ -430,7 +465,7 @@
 	 * @since 2.0.0
 	 * @access public
 	 *
-	 * @param int|string $id User's ID
+	 * @param int|string|stdClass|WP_User $id User's ID, a WP_User object, or a user object from the DB.
 	 * @param string $name Optional. User's username
 	 * @param int $blog_id Optional Blog ID, defaults to current blog.
 	 * @return WP_User
@@ -448,6 +483,14 @@
 			);
 		}
 
+		if ( is_a( $id, 'WP_User' ) ) {
+			$this->init( $id->data, $blog_id );
+			return;
+		} elseif ( is_object( $id ) ) {
+			$this->init( $id, $blog_id );
+			return;
+		}
+
 		if ( ! empty( $id ) && ! is_numeric( $id ) ) {
 			$name = $id;
 			$id = 0;
@@ -636,6 +679,17 @@
 		return $this->__isset( $key );
 	}
 
+	/*
+	 * Return an array representation.
+	 *
+	 * @since 3.5.0
+	 *
+	 * @return array Array representation.
+	 */
+	function to_array() {
+		return get_object_vars( $this->data );
+	}
+
 	/**
 	 * Set up capability object properties.
 	 *
@@ -685,7 +739,7 @@
 
 		//Filter out caps that are not role names and assign to $this->roles
 		if ( is_array( $this->caps ) )
-			$this->roles = array_filter( array_keys( $this->caps ), array( &$wp_roles, 'is_role' ) );
+			$this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) );
 
 		//Build $allcaps from role caps, overlay user's $caps
 		$this->allcaps = array();
@@ -743,12 +797,12 @@
 	 * @param string $role Role name.
 	 */
 	function set_role( $role ) {
+		if ( 1 == count( $this->roles ) && $role == current( $this->roles ) )
+			return;
+
 		foreach ( (array) $this->roles as $oldrole )
 			unset( $this->caps[$oldrole] );
 
-		if ( 1 == count( $this->roles ) && $role == $this->roles[0] )
-			return;
-
 		if ( !empty( $role ) ) {
 			$this->caps[$role] = true;
 			$this->roles = array( $role => true );
@@ -828,7 +882,7 @@
 	 * @param string $cap Capability name.
 	 */
 	function remove_cap( $cap ) {
-		if ( empty( $this->caps[$cap] ) )
+		if ( ! isset( $this->caps[$cap] ) )
 			return;
 		unset( $this->caps[$cap] );
 		update_user_meta( $this->ID, $this->cap_key, $this->caps );
@@ -947,20 +1001,19 @@
 		$caps[] = 'promote_users';
 		break;
 	case 'edit_user':
+	case 'edit_users':
 		// Allow user to edit itself
-		if ( isset( $args[0] ) && $user_id == $args[0] )
+		if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] )
 			break;
-		// Fall through
-	case 'edit_users':
+
 		// If multisite these caps are allowed only for super admins.
 		if ( is_multisite() && !is_super_admin( $user_id ) )
 			$caps[] = 'do_not_allow';
 		else
-			$caps[] = 'edit_users'; // Explicit due to primitive fall through
+			$caps[] = 'edit_users'; // edit_user maps to edit_users.
 		break;
 	case 'delete_post':
 	case 'delete_page':
-		$author_data = get_userdata( $user_id );
 		$post = get_post( $args[0] );
 
 		if ( 'revision' == $post->post_type ) {
@@ -977,12 +1030,13 @@
 			break;
 		}
 
-		if ( '' != $post->post_author ) {
-			$post_author_data = get_userdata( $post->post_author );
-		} else {
-			// No author set yet, so default to current user for cap checks.
-			$post_author_data = $author_data;
-		}
+		$post_author_id = $post->post_author;
+
+		// If no author set yet, default to current user for cap checks.
+		if ( ! $post_author_id )
+			$post_author_id = $user_id;
+
+		$post_author_data = $post_author_id == get_current_user_id() ? wp_get_current_user() : get_userdata( $post_author_id );
 
 		// If the user is the author...
 		if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) {
@@ -1010,7 +1064,6 @@
 		// edit_others_posts
 	case 'edit_post':
 	case 'edit_page':
-		$author_data = get_userdata( $user_id );
 		$post = get_post( $args[0] );
 
 		if ( 'revision' == $post->post_type ) {
@@ -1027,14 +1080,14 @@
 			break;
 		}
 
-		if ( '' != $post->post_author ) {
-			$post_author_data = get_userdata( $post->post_author );
-		} else {
-			// No author set yet, so default to current user for cap checks.
-			$post_author_data = $author_data;
-		}
+		$post_author_id = $post->post_author;
 
-		//echo "current user id : $user_id, post author id: " . $post_author_data->ID . "<br />";
+		// If no author set yet, default to current user for cap checks.
+		if ( ! $post_author_id )
+			$post_author_id = $user_id;
+
+		$post_author_data = $post_author_id == get_current_user_id() ? wp_get_current_user() : get_userdata( $post_author_id );
+
 		// If the user is the author...
 		if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) {
 			// If the post is published...
@@ -1059,7 +1112,6 @@
 		break;
 	case 'read_post':
 	case 'read_page':
-		$author_data = get_userdata( $user_id );
 		$post = get_post( $args[0] );
 
 		if ( 'revision' == $post->post_type ) {
@@ -1082,12 +1134,13 @@
 			break;
 		}
 
-		if ( '' != $post->post_author ) {
-			$post_author_data = get_userdata( $post->post_author );
-		} else {
-			// No author set yet, so default to current user for cap checks.
-			$post_author_data = $author_data;
-		}
+		$post_author_id = $post->post_author;
+
+		// If no author set yet, default to current user for cap checks.
+		if ( ! $post_author_id )
+			$post_author_id = $user_id;
+
+		$post_author_data = $post_author_id == get_current_user_id() ? wp_get_current_user() : get_userdata( $post_author_id );
 
 		if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID )
 			$caps[] = $post_type->cap->read;
@@ -1096,6 +1149,12 @@
 		else
 			$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
 		break;
+	case 'publish_post':
+		$post = get_post( $args[0] );
+		$post_type = get_post_type_object( $post->post_type );
+
+		$caps[] = $post_type->cap->publish_posts;
+		break;
 	case 'edit_post_meta':
 	case 'delete_post_meta':
 	case 'add_post_meta':
@@ -1138,11 +1197,16 @@
 	case 'edit_files':
 	case 'edit_plugins':
 	case 'edit_themes':
-		if ( defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT ) {
+		// Disallow the file editors.
+		if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT )
+			$caps[] = 'do_not_allow';
+		elseif ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
 			$caps[] = 'do_not_allow';
-			break;
-		}
-		// Fall through if not DISALLOW_FILE_EDIT.
+		elseif ( is_multisite() && ! is_super_admin( $user_id ) )
+			$caps[] = 'do_not_allow';
+		else
+			$caps[] = $cap;
+		break;
 	case 'update_plugins':
 	case 'delete_plugins':
 	case 'install_plugins':
@@ -1150,23 +1214,31 @@
 	case 'delete_themes':
 	case 'install_themes':
 	case 'update_core':
-		// Disallow anything that creates, deletes, or edits core, plugin, or theme files.
+		// Disallow anything that creates, deletes, or updates core, plugin, or theme files.
 		// Files in uploads are excepted.
-		if ( defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS ) {
+		if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
+			$caps[] = 'do_not_allow';
+		elseif ( is_multisite() && ! is_super_admin( $user_id ) )
 			$caps[] = 'do_not_allow';
-			break;
+		else
+			$caps[] = $cap;
+		break;
+	case 'activate_plugins':
+		$caps[] = $cap;
+		if ( is_multisite() ) {
+			// update_, install_, and delete_ are handled above with is_super_admin().
+			$menu_perms = get_site_option( 'menu_items', array() );
+			if ( empty( $menu_perms['plugins'] ) )
+				$caps[] = 'manage_network_plugins';
 		}
-		// Fall through if not DISALLOW_FILE_MODS.
+		break;
 	case 'delete_user':
 	case 'delete_users':
-		// If multisite these caps are allowed only for super admins.
-		if ( is_multisite() && !is_super_admin( $user_id ) ) {
+		// If multisite only super admins can delete users.
+		if ( is_multisite() && ! is_super_admin( $user_id ) )
 			$caps[] = 'do_not_allow';
-		} else {
-			if ( 'delete_user' == $cap )
-				$cap = 'delete_users';
-			$caps[] = $cap;
-		}
+		else
+			$caps[] = 'delete_users'; // delete_user maps to delete_users.
 		break;
 	case 'create_users':
 		if ( !is_multisite() )
@@ -1176,6 +1248,12 @@
 		else
 			$caps[] = 'do_not_allow';
 		break;
+	case 'manage_links' :
+		if ( get_option( 'link_manager_enabled' ) )
+			$caps[] = $cap;
+		else
+			$caps[] = 'do_not_allow';
+		break;
 	default:
 		// Handle meta capabilities for custom post types.
 		$post_type_meta_caps = _post_type_meta_capabilities();
@@ -1221,21 +1299,23 @@
  * @return bool
  */
 function current_user_can_for_blog( $blog_id, $capability ) {
+	if ( is_multisite() )
+		switch_to_blog( $blog_id );
+
 	$current_user = wp_get_current_user();
 
 	if ( empty( $current_user ) )
 		return false;
 
-	// Create new object to avoid stomping the global current_user.
-	$user = new WP_User( $current_user->ID) ;
-
-	// Set the blog id. @todo add blog id arg to WP_User constructor?
-	$user->for_blog( $blog_id );
-
 	$args = array_slice( func_get_args(), 2 );
 	$args = array_merge( array( $capability ), $args );
 
-	return call_user_func_array( array( &$user, 'has_cap' ), $args );
+	$can = call_user_func_array( array( $current_user, 'has_cap' ), $args );
+
+	if ( is_multisite() )
+		restore_current_blog();
+
+	return $can;
 }
 
 /**
@@ -1251,15 +1331,15 @@
 	if ( !$post = get_post($post) )
 		return false;
 
-	$author = new WP_User( $post->post_author );
+	$author = get_userdata( $post->post_author );
 
-	if ( empty( $author->ID ) )
+	if ( ! $author )
 		return false;
 
 	$args = array_slice( func_get_args(), 2 );
 	$args = array_merge( array( $capability ), $args );
 
-	return call_user_func_array( array( &$author, 'has_cap' ), $args );
+	return call_user_func_array( array( $author, 'has_cap' ), $args );
 }
 
 /**
@@ -1273,7 +1353,7 @@
  */
 function user_can( $user, $capability ) {
 	if ( ! is_object( $user ) )
-		$user = new WP_User( $user );
+		$user = get_userdata( $user );
 
 	if ( ! $user || ! $user->exists() )
 		return false;
@@ -1281,7 +1361,7 @@
 	$args = array_slice( func_get_args(), 2 );
 	$args = array_merge( array( $capability ), $args );
 
-	return call_user_func_array( array( &$user, 'has_cap' ), $args );
+	return call_user_func_array( array( $user, 'has_cap' ), $args );
 }
 
 /**
@@ -1367,12 +1447,12 @@
  * @return bool True if the user is a site admin.
  */
 function is_super_admin( $user_id = false ) {
-	if ( $user_id )
-		$user = new WP_User( $user_id );
+	if ( ! $user_id || $user_id == get_current_user_id() )
+		$user = wp_get_current_user();
 	else
-		$user = wp_get_current_user();
+		$user = get_userdata( $user_id );
 
-	if ( ! $user->exists() )
+	if ( ! $user || ! $user->exists() )
 		return false;
 
 	if ( is_multisite() ) {