<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[12722] trunk/wp-admin: merge wp-admin user, plugins, themes, upgrade ,
  See #11644</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.wordpress.org/changeset/12722">12722</a></dd>
<dt>Author</dt> <dd>wpmuguru</dd>
<dt>Date</dt> <dd>2010-01-14 02:02:19 +0000 (Thu, 14 Jan 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>merge wp-admin user, plugins, themes, upgrade , See <a href="http://trac.wordpress.org/ticket/11644">#11644</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpadminpluginsphp">trunk/wp-admin/plugins.php</a></li>
<li><a href="#trunkwpadminthemesphp">trunk/wp-admin/themes.php</a></li>
<li><a href="#trunkwpadminupgradephp">trunk/wp-admin/upgrade.php</a></li>
<li><a href="#trunkwpadminusereditphp">trunk/wp-admin/user-edit.php</a></li>
<li><a href="#trunkwpadminusernewphp">trunk/wp-admin/user-new.php</a></li>
<li><a href="#trunkwpadminusersphp">trunk/wp-admin/users.php</a></li>
</ul>

<h3>Property Changed</h3>
<ul>
<li><a href="#trunkwpadmin">trunk/wp-admin/</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpadmin"></a>
<div class="propset"><h4>Property changes: trunk/wp-admin</h4>
<pre class="diff"><span>
<span class="cx">Name: svn:ignore
</span><span class="cx">   + .themes.php.swp
</span><span class="cx">.user-edit.php.swp
</span><span class="cx">.user-new.php.swp
</span><span class="cx">.users.php.swp
</span></span></pre></div>
<a id="trunkwpadminpluginsphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/plugins.php (12721 => 12722)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/plugins.php        2010-01-13 19:06:47 UTC (rev 12721)
+++ trunk/wp-admin/plugins.php        2010-01-14 02:02:19 UTC (rev 12722)
</span><span class="lines">@@ -231,8 +231,10 @@
</span><span class="cx"> add_thickbox();
</span><span class="cx"> 
</span><span class="cx"> $help = '&lt;p&gt;' . __('Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.') . '&lt;/p&gt;';
</span><ins>+if ( !is_multisite() || is_super_admin() ) {
</ins><span class="cx"> $help .= '&lt;p&gt;' . sprintf(__('If something goes wrong with a plugin and you can&amp;#8217;t use WordPress, delete or rename that file in the &lt;code&gt;%s&lt;/code&gt; directory and it will be automatically deactivated.'), WP_PLUGIN_DIR) . '&lt;/p&gt;';
</span><span class="cx"> $help .= '&lt;p&gt;' . sprintf(__('You can find additional plugins for your site by using the new &lt;a href=&quot;%1$s&quot;&gt;Plugin Browser/Installer&lt;/a&gt; functionality or by browsing the &lt;a href=&quot;http://wordpress.org/extend/plugins/&quot;&gt;WordPress Plugin Directory&lt;/a&gt; directly and installing manually.  To &lt;em&gt;manually&lt;/em&gt; install a plugin you generally just need to upload the plugin file into your &lt;code&gt;%2$s&lt;/code&gt; directory.  Once a plugin has been installed, you may activate it here.'), 'plugin-install.php', WP_PLUGIN_DIR) . '&lt;/p&gt;';
</span><ins>+}
</ins><span class="cx"> 
</span><span class="cx"> add_contextual_help('plugins', $help);
</span><span class="cx"> 
</span><span class="lines">@@ -282,11 +284,11 @@
</span><span class="cx"> 
</span><span class="cx"> &lt;div class=&quot;wrap&quot;&gt;
</span><span class="cx"> &lt;?php screen_icon(); ?&gt;
</span><del>-&lt;h2&gt;&lt;?php echo esc_html( $title ); ?&gt; &lt;a href=&quot;plugin-install.php&quot; class=&quot;button add-new-h2&quot;&gt;&lt;?php echo esc_html_x('Add New', 'plugin'); ?&gt;&lt;/a&gt;&lt;/h2&gt;
</del><ins>+&lt;h2&gt;&lt;?php echo esc_html( $title ); if ( !is_multisite() || is_super_admin() ) { ?&gt; &lt;a href=&quot;plugin-install.php&quot; class=&quot;button add-new-h2&quot;&gt;&lt;?php echo esc_html_x('Add New', 'plugin'); ?&gt;&lt;/a&gt;&lt;?php } ?&gt;&lt;/h2&gt;
</ins><span class="cx"> 
</span><span class="cx"> &lt;?php
</span><span class="cx"> 
</span><del>-$all_plugins = get_plugins();
</del><ins>+$all_plugins = apply_filters( 'all_plugins', get_plugins() );
</ins><span class="cx"> $search_plugins = array();
</span><span class="cx"> $active_plugins = array();
</span><span class="cx"> $inactive_plugins = array();
</span><span class="lines">@@ -323,6 +325,10 @@
</span><span class="cx">         $upgrade_plugins[ $plugin_file ] = $plugin_data;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+if ( is_multisite() &amp;&amp; !is_super_admin() ) {
+        $upgrade_plugins = false;
+}
+
</ins><span class="cx"> $total_all_plugins = count($all_plugins);
</span><span class="cx"> $total_inactive_plugins = count($inactive_plugins);
</span><span class="cx"> $total_active_plugins = count($active_plugins);
</span><span class="lines">@@ -515,6 +521,8 @@
</span><span class="cx"> &lt;/p&gt;
</span><span class="cx"> &lt;/form&gt;
</span><span class="cx"> 
</span><ins>+&lt;?php do_action( 'pre_current_active_plugins', $all_plugins ) ?&gt;
+
</ins><span class="cx"> &lt;form method=&quot;post&quot; action=&quot;&lt;?php echo admin_url('plugins.php') ?&gt;&quot;&gt;
</span><span class="cx"> &lt;?php wp_nonce_field('bulk-manage-plugins') ?&gt;
</span><span class="cx"> &lt;input type=&quot;hidden&quot; name=&quot;plugin_status&quot; value=&quot;&lt;?php echo esc_attr($status) ?&gt;&quot; /&gt;
</span></span></pre></div>
<a id="trunkwpadminthemesphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/themes.php (12721 => 12722)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/themes.php        2010-01-13 19:06:47 UTC (rev 12721)
+++ trunk/wp-admin/themes.php        2010-01-14 02:02:19 UTC (rev 12722)
</span><span class="lines">@@ -12,6 +12,30 @@
</span><span class="cx"> if ( !current_user_can('switch_themes') )
</span><span class="cx">         wp_die( __( 'Cheatin&amp;#8217; uh?' ) );
</span><span class="cx"> 
</span><ins>+if ( is_multisite() ) {
+        $themes = get_themes();
+        $ct = current_theme_info();
+        $allowed_themes = apply_filters(&quot;allowed_themes&quot;, get_site_allowed_themes() ); 
+        if( $allowed_themes == false )
+                $allowed_themes = array();
+
+        $blog_allowed_themes = wpmu_get_blog_allowedthemes();
+        if( is_array( $blog_allowed_themes ) )
+                $allowed_themes = array_merge( $allowed_themes, $blog_allowed_themes );
+        if( $blog_id != 1 )
+                unset( $allowed_themes[ &quot;h3&quot; ] );
+
+        if( isset( $allowed_themes[ wp_specialchars( $ct-&gt;stylesheet ) ] ) == false )
+                $allowed_themes[ wp_specialchars( $ct-&gt;stylesheet ) ] = true;
+
+        reset( $themes );
+        foreach( $themes as $key =&gt; $theme ) {
+                if( isset( $allowed_themes[ wp_specialchars( $theme[ 'Stylesheet' ] ) ] ) == false ) {
+                        unset( $themes[ $key ] );
+                }
+        }
+        reset( $themes );
+}
</ins><span class="cx"> if ( isset($_GET['action']) ) {
</span><span class="cx">         if ( 'activate' == $_GET['action'] ) {
</span><span class="cx">                 check_admin_referer('switch-theme_' . $_GET['template']);
</span><span class="lines">@@ -32,7 +56,7 @@
</span><span class="cx"> $parent_file = 'themes.php';
</span><span class="cx"> 
</span><span class="cx"> $help = '&lt;p&gt;' . __('Themes give your WordPress style. Once a theme is installed, you may preview it, activate it or deactivate it here.') . '&lt;/p&gt;';
</span><del>-if ( current_user_can('install_themes') ) {
</del><ins>+if ( ( !is_multisite() &amp;&amp; current_user_can('install_themes') ) || is_super_admin() ) {
</ins><span class="cx">         $help .= '&lt;p&gt;' . sprintf(__('You can find additional themes for your site by using the new &lt;a href=&quot;%1$s&quot;&gt;Theme Browser/Installer&lt;/a&gt; functionality or by browsing the &lt;a href=&quot;http://wordpress.org/extend/themes/&quot;&gt;WordPress Theme Directory&lt;/a&gt; directly and installing manually.  To install a theme &lt;em&gt;manually&lt;/em&gt;, &lt;a href=&quot;%2$s&quot;&gt;upload its ZIP archive with the new uploader&lt;/a&gt; or copy its folder via FTP into your &lt;code&gt;wp-content/themes&lt;/code&gt; directory.'), 'theme-install.php', 'theme-install.php?tab=upload' ) . '&lt;/p&gt;';
</span><span class="cx">         $help .= '&lt;p&gt;' . __('Once a theme is uploaded, you should see it on this page.') . '&lt;/p&gt;' ;
</span><span class="cx"> }
</span><span class="lines">@@ -43,6 +67,9 @@
</span><span class="cx"> wp_enqueue_script( 'theme-preview' );
</span><span class="cx"> 
</span><span class="cx"> require_once('admin-header.php');
</span><ins>+if( is_multisite() &amp;&amp; is_super_admin() ) {
+        ?&gt;&lt;div id=&quot;message0&quot; class=&quot;updated fade&quot;&gt;&lt;p&gt;&lt;?php _e('Administrator: new themes must be activated in the &lt;a href=&quot;wpmu-themes.php&quot;&gt;Themes Admin&lt;/a&gt; page before they appear here.'); ?&gt;&lt;/p&gt;&lt;/div&gt;&lt;?php
+}
</ins><span class="cx"> ?&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;?php if ( ! validate_current_theme() ) : ?&gt;
</span><span class="lines">@@ -58,7 +85,8 @@
</span><span class="cx"> &lt;?php endif; ?&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;?php
</span><del>-$themes = get_themes();
</del><ins>+if ( !is_multisite() )
+        $themes = get_themes();
</ins><span class="cx"> $ct = current_theme_info();
</span><span class="cx"> unset($themes[$ct-&gt;name]);
</span><span class="cx"> 
</span><span class="lines">@@ -97,6 +125,10 @@
</span><span class="cx">  */
</span><span class="cx"> function theme_update_available( $theme ) {
</span><span class="cx">         static $themes_update;
</span><ins>+
+        if ( is_multisite() &amp;&amp; !is_super_admin() )
+                return;
+
</ins><span class="cx">         if ( !isset($themes_update) )
</span><span class="cx">                 $themes_update = get_site_transient('update_themes');
</span><span class="cx"> 
</span><span class="lines">@@ -127,7 +159,7 @@
</span><span class="cx"> 
</span><span class="cx"> &lt;div class=&quot;wrap&quot;&gt;
</span><span class="cx"> &lt;?php screen_icon(); ?&gt;
</span><del>-&lt;h2&gt;&lt;?php echo esc_html( $title ); ?&gt; &lt;a href=&quot;theme-install.php&quot; class=&quot;button add-new-h2&quot;&gt;&lt;?php echo esc_html_x('Add New', 'theme'); ?&gt;&lt;/a&gt;&lt;/h2&gt;
</del><ins>+&lt;h2&gt;&lt;?php echo esc_html( $title ); if ( !is_multisite() || is_super_admin() ) { ?&gt; &lt;a href=&quot;theme-install.php&quot; class=&quot;button add-new-h2&quot;&gt;&lt;?php echo esc_html_x('Add New', 'theme'); ?&gt;&lt;/a&gt;&lt;?php } ?&gt;&lt;/h2&gt;
</ins><span class="cx"> 
</span><span class="cx"> &lt;h3&gt;&lt;?php _e('Current Theme'); ?&gt;&lt;/h3&gt;
</span><span class="cx"> &lt;div id=&quot;current-theme&quot;&gt;
</span><span class="lines">@@ -138,7 +170,7 @@
</span><span class="cx">         /* translators: 1: theme title, 2: theme version, 3: theme author */
</span><span class="cx">         printf(__('%1$s %2$s by %3$s'), $ct-&gt;title, $ct-&gt;version, $ct-&gt;author) ; ?&gt;&lt;/h4&gt;
</span><span class="cx"> &lt;p class=&quot;theme-description&quot;&gt;&lt;?php echo $ct-&gt;description; ?&gt;&lt;/p&gt;
</span><del>-&lt;?php if ($ct-&gt;parent_theme) { ?&gt;
</del><ins>+&lt;?php if ( ( !is_multisite() || is_super_admin() ) &amp;&amp; $ct-&gt;parent_theme ) { ?&gt;
</ins><span class="cx">         &lt;p&gt;&lt;?php printf(__('The template files are located in &lt;code&gt;%2$s&lt;/code&gt;.  The stylesheet files are located in &lt;code&gt;%3$s&lt;/code&gt;.  &lt;strong&gt;%4$s&lt;/strong&gt; uses templates from &lt;strong&gt;%5$s&lt;/strong&gt;.  Changes made to the templates will affect both themes.'), $ct-&gt;title, str_replace( WP_CONTENT_DIR, '', $ct-&gt;template_dir ), str_replace( WP_CONTENT_DIR, '', $ct-&gt;stylesheet_dir ), $ct-&gt;title, $ct-&gt;parent_theme); ?&gt;&lt;/p&gt;
</span><span class="cx"> &lt;?php } else { ?&gt;
</span><span class="cx">         &lt;p&gt;&lt;?php printf(__('All of this theme&amp;#8217;s files are located in &lt;code&gt;%2$s&lt;/code&gt;.'), $ct-&gt;title, str_replace( WP_CONTENT_DIR, '', $ct-&gt;template_dir ), str_replace( WP_CONTENT_DIR, '', $ct-&gt;stylesheet_dir ) ); ?&gt;&lt;/p&gt;
</span><span class="lines">@@ -217,7 +249,7 @@
</span><span class="cx">         $actions = array();
</span><span class="cx">         $actions[] = '&lt;a href=&quot;' . $activate_link .  '&quot; class=&quot;activatelink&quot; title=&quot;' . $activate_text . '&quot;&gt;' . __('Activate') . '&lt;/a&gt;';
</span><span class="cx">         $actions[] = '&lt;a href=&quot;' . $preview_link . '&quot; class=&quot;thickbox thickbox-preview&quot; title=&quot;' . esc_attr(sprintf(__('Preview &amp;#8220;%s&amp;#8221;'), $theme_name)) . '&quot;&gt;' . __('Preview') . '&lt;/a&gt;';
</span><del>-        if ( current_user_can('update_themes') )
</del><ins>+        if ( ( !is_multisite() &amp;&amp; current_user_can('update_themes') ) || is_super_admin() )
</ins><span class="cx">                 $actions[] = '&lt;a class=&quot;submitdelete deletion&quot; href=&quot;' . wp_nonce_url(&quot;themes.php?action=delete&amp;amp;template=$stylesheet&quot;, 'delete-theme_' . $stylesheet) . '&quot; onclick=&quot;' . &quot;if ( confirm('&quot; . esc_js(sprintf( __(&quot;You are about to delete this theme '%s'\n  'Cancel' to stop, 'OK' to delete.&quot;), $theme_name )) . &quot;') ) {return true;}return false;&quot; . '&quot;&gt;' . __('Delete') . '&lt;/a&gt;';
</span><span class="cx">         $actions = apply_filters('theme_action_links', $actions, $themes[$theme_name]);
</span><span class="cx"> 
</span><span class="lines">@@ -233,7 +265,7 @@
</span><span class="cx">         printf(__('%1$s %2$s by %3$s'), $title, $version, $author) ; ?&gt;&lt;/h3&gt;
</span><span class="cx"> &lt;p class=&quot;description&quot;&gt;&lt;?php echo $description; ?&gt;&lt;/p&gt;
</span><span class="cx"> &lt;span class='action-links'&gt;&lt;?php echo $actions ?&gt;&lt;/span&gt;
</span><del>-        &lt;?php if ($parent_theme) {
</del><ins>+        &lt;?php if ( ( !is_multisite() || is_super_admin() ) &amp;&amp; $parent_theme ) {
</ins><span class="cx">         /* translators: 1: theme title, 2:  template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?&gt;
</span><span class="cx">         &lt;p&gt;&lt;?php printf(__('The template files are located in &lt;code&gt;%2$s&lt;/code&gt;.  The stylesheet files are located in &lt;code&gt;%3$s&lt;/code&gt;.  &lt;strong&gt;%4$s&lt;/strong&gt; uses templates from &lt;strong&gt;%5$s&lt;/strong&gt;.  Changes made to the templates will affect both themes.'), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ), $title, $parent_theme); ?&gt;&lt;/p&gt;
</span><span class="cx"> &lt;?php } else { ?&gt;
</span><span class="lines">@@ -266,10 +298,10 @@
</span><span class="cx"> &lt;?php
</span><span class="cx"> // List broken themes, if any.
</span><span class="cx"> $broken_themes = get_broken_themes();
</span><del>-if ( count($broken_themes) ) {
</del><ins>+if ( ( !is_multisite() || is_super_admin() ) &amp;&amp; count( $broken_themes ) ) {
</ins><span class="cx"> ?&gt;
</span><span class="cx"> 
</span><del>-&lt;h2&gt;&lt;?php _e('Broken Themes'); ?&gt;&lt;/h2&gt;
</del><ins>+&lt;h2&gt;&lt;?php _e('Broken Themes'); ?&gt; &lt;?php if ( is_multisite() ) _e( '(Site admin only)' ); ?&gt;&lt;/h2&gt;
</ins><span class="cx"> &lt;p&gt;&lt;?php _e('The following themes are installed but incomplete.  Themes must have a stylesheet and a template.'); ?&gt;&lt;/p&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;table id=&quot;broken-themes&quot;&gt;
</span></span></pre></div>
<a id="trunkwpadminupgradephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/upgrade.php (12721 => 12722)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/upgrade.php        2010-01-13 19:06:47 UTC (rev 12721)
+++ trunk/wp-admin/upgrade.php        2010-01-14 02:02:19 UTC (rev 12722)
</span><span class="lines">@@ -86,6 +86,11 @@
</span><span class="cx">                         $backto = stripslashes( urldecode( $backto ) );
</span><span class="cx">                         $backto = esc_url_raw( $backto  );
</span><span class="cx">                         $backto = wp_validate_redirect($backto, __get_option( 'home' ) . '/');
</span><ins>+                if( $wpdb-&gt;get_row( &quot;SELECT blog_id FROM {$wpdb-&gt;blog_versions} WHERE blog_id = '{$wpdb-&gt;blogid}'&quot; ) ) {
+                        $wpdb-&gt;query( &quot;UPDATE {$wpdb-&gt;blog_versions} SET db_version = '{$wp_db_version}' WHERE blog_id = '{$wpdb-&gt;blogid}'&quot; );
+                } else {
+                        $wpdb-&gt;query( &quot;INSERT INTO {$wpdb-&gt;blog_versions} ( `blog_id` , `db_version` , `last_updated` ) VALUES ( '{$wpdb-&gt;blogid}', '{$wp_db_version}', NOW());&quot; );
+                }
</ins><span class="cx"> ?&gt;
</span><span class="cx"> &lt;h2&gt;&lt;?php _e( 'Upgrade Complete' ); ?&gt;&lt;/h2&gt;
</span><span class="cx">         &lt;p&gt;&lt;?php _e( 'Your WordPress database has been successfully upgraded!' ); ?&gt;&lt;/p&gt;
</span></span></pre></div>
<a id="trunkwpadminusereditphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/user-edit.php (12721 => 12722)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/user-edit.php        2010-01-13 19:06:47 UTC (rev 12721)
+++ trunk/wp-admin/user-edit.php        2010-01-14 02:02:19 UTC (rev 12722)
</span><span class="lines">@@ -60,6 +60,11 @@
</span><span class="cx"> &lt;?php
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
+// Only allow site admins to edit every user. 
+if ( is_multisite() &amp;&amp; !defined( &quot;EDIT_ANY_USER&quot; ) &amp;&amp; !is_super_admin() &amp;&amp; $user_id != $current_user-&gt;ID ) 
+        wp_die( __( 'You do not have permission to edit this user.' ) ); 
+        
</ins><span class="cx"> switch ($action) {
</span><span class="cx"> case 'switchposts':
</span><span class="cx"> 
</span><span class="lines">@@ -81,7 +86,24 @@
</span><span class="cx"> else
</span><span class="cx">         do_action('edit_user_profile_update', $user_id);
</span><span class="cx"> 
</span><del>-$errors = edit_user($user_id);
</del><ins>+if ( !is_multisite() ) {
+        $errors = edit_user($user_id);
+} else {
+        // WPMU must delete the user from the current blog if WP added him after editing.
+        $delete_role = false;
+        $blog_prefix = $wpdb-&gt;get_blog_prefix();
+        if( $user_id != $current_user-&gt;ID ) {
+                $cap = $wpdb-&gt;get_var( &quot;SELECT meta_value FROM {$wpdb-&gt;usermeta} WHERE user_id = '{$user_id}' AND meta_key = '{$blog_prefix}capabilities' AND meta_value = 'a:0:{}'&quot; );
+                if( null == $cap &amp;&amp; $_POST[ 'role' ] == '' ) {
+                        $_POST[ 'role' ] = 'contributor';
+                        $delete_role = true;
+                }
+        }
+        if ( !isset( $errors ) || ( isset( $errors ) &amp;&amp; is_object( $errors ) &amp;&amp; false == $errors-&gt;get_error_codes() ) )
+                $errors = edit_user($user_id);
+        if( $delete_role ) // stops users being added to current blog when they are edited
+                update_usermeta( $user_id, $blog_prefix . 'capabilities' , '' );
+}
</ins><span class="cx"> 
</span><span class="cx"> if ( !is_wp_error( $errors ) ) {
</span><span class="cx">         $redirect = (IS_PROFILE_PAGE ? &quot;profile.php?&quot; : &quot;user-edit.php?user_id=$user_id&amp;&quot;). &quot;updated=true&quot;;
</span></span></pre></div>
<a id="trunkwpadminusernewphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/user-new.php (12721 => 12722)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/user-new.php        2010-01-13 19:06:47 UTC (rev 12721)
+++ trunk/wp-admin/user-new.php        2010-01-14 02:02:19 UTC (rev 12722)
</span><span class="lines">@@ -15,21 +15,89 @@
</span><span class="cx"> /** WordPress Registration API */
</span><span class="cx"> require_once( ABSPATH . WPINC . '/registration.php');
</span><span class="cx"> 
</span><ins>+if ( is_multisite() ) {
+        function admin_created_user_email( $text ) {
+                return sprintf( __( &quot;Hi,
+You've been invited to join '%s' at
+%s as a %s.
+If you do not want to join this blog please ignore
+this email. This invitation will expire in a few days.
+
+Please click the following link to activate your user account:
+%%s&quot; ), get_bloginfo('name'), site_url(), wp_specialchars( $_REQUEST[ 'role' ] ) );
+        }
+        add_filter( 'wpmu_signup_user_notification_email', 'admin_created_user_email' );
+
+        function admin_created_user_subject( $text ) {
+                return &quot;[&quot; . get_bloginfo('name') . &quot;] Your blog invite&quot;;
+        }
+}
+
</ins><span class="cx"> if ( isset($_REQUEST['action']) &amp;&amp; 'adduser' == $_REQUEST['action'] ) {
</span><span class="cx">         check_admin_referer('add-user');
</span><span class="cx"> 
</span><span class="cx">         if ( ! current_user_can('create_users') )
</span><span class="cx">                 wp_die(__('You can&amp;#8217;t create users.'));
</span><span class="cx"> 
</span><del>-        $user_id = add_user();
</del><ins>+        if ( !is_multisite() ) {
+                $user_id = add_user();
</ins><span class="cx"> 
</span><del>-        if ( is_wp_error( $user_id ) ) {
-                $add_user_errors = $user_id;
</del><ins>+                if ( is_wp_error( $user_id ) ) {
+                        $add_user_errors = $user_id;
+                } else {
+                        $new_user_login = apply_filters('pre_user_login', sanitize_user(stripslashes($_REQUEST['user_login']), true));
+                        $redirect = 'users.php?usersearch='. urlencode($new_user_login) . '&amp;update=add';
+                        wp_redirect( $redirect . '#user-' . $user_id );
+                        die();
+                }
</ins><span class="cx">         } else {
</span><del>-                $new_user_login = apply_filters('pre_user_login', sanitize_user(stripslashes($_REQUEST['user_login']), true));
-                $redirect = 'users.php?usersearch='. urlencode($new_user_login) . '&amp;update=add';
-                wp_redirect( $redirect . '#user-' . $user_id );
-                die();
</del><ins>+                $user_login = preg_replace( &quot;/\s+/&quot;, '', sanitize_user( $_REQUEST[ 'user_login' ], true ) );
+                $user_details = $wpdb-&gt;get_row( $wpdb-&gt;prepare( &quot;SELECT * FROM {$wpdb-&gt;users} WHERE user_login = %s AND user_email = %s&quot;, $user_login, $_REQUEST[ 'email' ] ) );
+                if( $user_details ) {
+                        // Adding an existing user to this blog
+                        $new_user_email = wp_specialchars(trim($_REQUEST['email']));
+                        $redirect = 'user-new.php';
+                        $username = $user_details-&gt;user_login;
+                        $user_id = $user_details-&gt;ID;
+                        if( ($username != null &amp;&amp; is_site_admin( $username ) == false ) &amp;&amp; ( array_key_exists($blog_id, get_blogs_of_user($user_id)) ) ) {
+                                $redirect = add_query_arg( array('update' =&gt; 'addexisting'), 'user-new.php' );
+                        } else {
+                                if ( isset( $_POST[ 'noconfirmation' ] ) &amp;&amp; is_site_admin() ) {
+                                        add_existing_user_to_blog( array( 'user_id' =&gt; $user_id, 'role' =&gt; $_REQUEST[ 'role' ] ) );
+                                        $redirect = add_query_arg( array('update' =&gt; 'addnoconfirmation'), 'user-new.php' );
+                                } else {
+                                        $newuser_key = substr( md5( $user_id ), 0, 5 );
+                                        add_option( 'new_user_' . $newuser_key, array( 'user_id' =&gt; $user_id, 'email' =&gt; $user_details-&gt;user_email, 'role' =&gt; $_REQUEST[ 'role' ] ) );
+                                        $message = __(&quot;Hi,\n\nYou have been invited to join '%s' at\n%s as a %s.\nPlease click the following link to confirm the invite:\n%s\n&quot;);
+                                        wp_mail( $new_user_email, sprintf( __( '[%s] Joining confirmation' ), get_option( 'blogname' ) ),  sprintf($message, get_option('blogname'), site_url(), $_REQUEST[ 'role' ], site_url(&quot;/newbloguser/$newuser_key/&quot;)));
+                                        $redirect = add_query_arg( array('update' =&gt; 'add'), 'user-new.php' );
+                                }
+                        }
+                        wp_redirect( $redirect );
+                        die();
+                } else {
+                        // Adding a new user to this blog
+                        $user_details = wpmu_validate_user_signup( $_REQUEST[ 'user_login' ], $_REQUEST[ 'email' ] );
+                        unset( $user_details[ 'errors' ]-&gt;errors[ 'user_email_used' ] );
+                        if ( is_wp_error( $user_details[ 'errors' ] ) &amp;&amp; !empty( $user_details[ 'errors' ]-&gt;errors ) ) {
+                                $add_user_errors = $user_details[ 'errors' ];
+                        } else {
+                                $new_user_login = apply_filters('pre_user_login', sanitize_user(stripslashes($_REQUEST['user_login']), true));
+                                if ( isset( $_POST[ 'noconfirmation' ] ) &amp;&amp; is_site_admin() ) {
+                                        add_filter( 'wpmu_signup_user_notification', create_function('', '{return false;}') ); // Disable confirmation email
+                                }
+                                wpmu_signup_user( $new_user_login, $_REQUEST[ 'email' ], array( 'add_to_blog' =&gt; $wpdb-&gt;blogid, 'new_role' =&gt; $_REQUEST[ 'role' ] ) );
+                                if ( isset( $_POST[ 'noconfirmation' ] ) &amp;&amp; is_site_admin() ) {
+                                        $key = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT activation_key FROM {$wpdb-&gt;signups} WHERE user_login = %s AND user_email = %s&quot;, $new_user_login, $_REQUEST[ 'email' ] ) );
+                                        wpmu_activate_signup( $key );
+                                        $redirect = add_query_arg( array('update' =&gt; 'addnoconfirmation'), 'user-new.php' );
+                                } else {
+                                        $redirect = add_query_arg( array('update' =&gt; 'newuserconfimation'), 'user-new.php' );
+                                }
+                                wp_redirect( $redirect );
+                                die();
+                        }
+                }
</ins><span class="cx">         }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -42,6 +110,22 @@
</span><span class="cx"> 
</span><span class="cx"> require_once ('admin-header.php');
</span><span class="cx"> 
</span><ins>+if ( is_multisite() ) {
+        switch( $_GET[ 'update' ] ) {
+                case &quot;newuserconfimation&quot;:
+                        $messages[] = '&lt;div id=&quot;message&quot; class=&quot;updated fade&quot;&gt;&lt;p&gt;' . __('Invitation email sent to new user. A confirmation link must be clicked before their account is created.') . '&lt;/p&gt;&lt;/div&gt;';
+                        break;
+                case &quot;add&quot;:
+                        $messages[] = '&lt;div id=&quot;message&quot; class=&quot;updated fade&quot;&gt;&lt;p&gt;' . __('Invitation email sent to user. A confirmation link must be clicked for them to be added to your blog.') . '&lt;/p&gt;&lt;/div&gt;';
+                        break;
+                case &quot;addnoconfirmation&quot;:
+                        $messages[] = '&lt;div id=&quot;message&quot; class=&quot;updated fade&quot;&gt;&lt;p&gt;' . __('User has been added to your blog.') . '&lt;/p&gt;&lt;/div&gt;';
+                        break;
+                case &quot;addexisting&quot;:
+                        $messages[] = '&lt;div id=&quot;message&quot; class=&quot;updated fade&quot;&gt;&lt;p&gt;' . __('That user is already a member of this blog.') . '&lt;/p&gt;&lt;/div&gt;';
+                        break;
+        }
+}
</ins><span class="cx"> ?&gt;
</span><span class="cx"> &lt;div class=&quot;wrap&quot;&gt;
</span><span class="cx"> &lt;?php screen_icon(); ?&gt;
</span><span class="lines">@@ -74,10 +158,15 @@
</span><span class="cx"> &lt;div id=&quot;ajax-response&quot;&gt;&lt;/div&gt;
</span><span class="cx"> 
</span><span class="cx"> &lt;?php
</span><ins>+if ( !is_multisite() ) {
</ins><span class="cx">         if ( get_option('users_can_register') )
</span><span class="cx">                 echo '&lt;p&gt;' . sprintf(__('Users can &lt;a href=&quot;%1$s&quot;&gt;register themselves&lt;/a&gt; or you can manually create users here.'), site_url('wp-register.php')) . '&lt;/p&gt;';
</span><span class="cx">         else
</span><span class="cx">                 echo '&lt;p&gt;' . sprintf(__('Users cannot currently &lt;a href=&quot;%1$s&quot;&gt;register themselves&lt;/a&gt;, but you can manually create users here.'), admin_url('options-general.php#users_can_register')) . '&lt;/p&gt;';
</span><ins>+} else {
+        echo '&lt;p&gt;' . __( 'You can add new users to your blog in two ways:' ) . '&lt;ol&gt;&lt;li&gt; ' . __( 'Enter the username and email address of an existing user on this site.' ) . '&lt;/li&gt;&lt;li&gt; ' . __( 'Enter the username and the email address of a person who is not already a member of this site. Choose the username carefully, it cannot be changed.' ) . '&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;';
+        echo '&lt;p&gt;' . __( 'That person will be sent an email asking them to click a link confirming the invite. New users will then be sent an email with a randomly generated password and a login link.' ) . '&lt;/p&gt;';
+}
</ins><span class="cx"> ?&gt;
</span><span class="cx"> &lt;form action=&quot;#add-new-user&quot; method=&quot;post&quot; name=&quot;adduser&quot; id=&quot;adduser&quot; class=&quot;add:users: validate&quot;&gt;
</span><span class="cx"> &lt;?php wp_nonce_field('add-user') ?&gt;
</span><span class="lines">@@ -92,6 +181,7 @@
</span><span class="cx"> $new_user_send_password = !$_POST || isset($_POST['send_password']);
</span><span class="cx"> ?&gt;
</span><span class="cx"> &lt;table class=&quot;form-table&quot;&gt;
</span><ins>+&lt;?php if ( !is_multisite() ) { ?&gt;
</ins><span class="cx">         &lt;tr class=&quot;form-field form-required&quot;&gt;
</span><span class="cx">                 &lt;th scope=&quot;row&quot;&gt;&lt;label for=&quot;user_login&quot;&gt;&lt;?php _e('Username'); ?&gt; &lt;span class=&quot;description&quot;&gt;&lt;?php _e('(required)'); ?&gt;&lt;/span&gt;&lt;/label&gt;
</span><span class="cx">                 &lt;input name=&quot;action&quot; type=&quot;hidden&quot; id=&quot;action&quot; value=&quot;adduser&quot; /&gt;&lt;/th&gt;
</span><span class="lines">@@ -130,7 +220,16 @@
</span><span class="cx">                 &lt;td&gt;&lt;label for=&quot;send_password&quot;&gt;&lt;input type=&quot;checkbox&quot; name=&quot;send_password&quot; id=&quot;send_password&quot; &lt;?php checked($new_user_send_password, true); ?&gt; /&gt; &lt;?php _e('Send this password to the new user by email.'); ?&gt;&lt;/label&gt;&lt;/td&gt;
</span><span class="cx">         &lt;/tr&gt;
</span><span class="cx"> &lt;?php endif; ?&gt;
</span><del>-
</del><ins>+&lt;?php } else { // multisite ?&gt;
+        &lt;tr class=&quot;form-field form-required&quot;&gt;
+                &lt;th scope=&quot;row&quot;&gt;&lt;label for=&quot;user_login&quot;&gt;&lt;?php _e('Username (required)') ?&gt;&lt;/label&gt;&lt;input name=&quot;action&quot; type=&quot;hidden&quot; id=&quot;action&quot; value=&quot;adduser&quot; /&gt;&lt;/th&gt;
+                &lt;td &gt;&lt;input name=&quot;user_login&quot; type=&quot;text&quot; id=&quot;user_login&quot; value=&quot;&lt;?php echo $new_user_login; ?&gt;&quot; aria-required=&quot;true&quot; /&gt;&lt;/td&gt;
+        &lt;/tr&gt;
+        &lt;tr class=&quot;form-field form-required&quot;&gt;
+                &lt;th scope=&quot;row&quot;&gt;&lt;label for=&quot;email&quot;&gt;&lt;?php _e('E-mail (required)') ?&gt;&lt;/label&gt;&lt;/th&gt;
+                &lt;td&gt;&lt;input name=&quot;email&quot; type=&quot;text&quot; id=&quot;email&quot; value=&quot;&lt;?php echo $new_user_email; ?&gt;&quot; /&gt;&lt;/td&gt;
+        &lt;/tr&gt;
+&lt;?php } ?&gt;
</ins><span class="cx">         &lt;tr class=&quot;form-field&quot;&gt;
</span><span class="cx">                 &lt;th scope=&quot;row&quot;&gt;&lt;label for=&quot;role&quot;&gt;&lt;?php _e('Role'); ?&gt;&lt;/label&gt;&lt;/th&gt;
</span><span class="cx">                 &lt;td&gt;&lt;select name=&quot;role&quot; id=&quot;role&quot;&gt;
</span><span class="lines">@@ -142,6 +241,13 @@
</span><span class="cx">                         &lt;/select&gt;
</span><span class="cx">                 &lt;/td&gt;
</span><span class="cx">         &lt;/tr&gt;
</span><ins>+
+        &lt;?php if ( is_multisite() &amp;&amp; is_super_admin() ) { ?&gt;
+        &lt;tr class=&quot;form-field&quot;&gt;
+                &lt;th scope=&quot;row&quot;&gt;&lt;label for=&quot;noconfirmation&quot;&gt;&lt;?php _e('Skip Confirmation Email') ?&gt;&lt;/label&gt;&lt;/th&gt;
+                &lt;td&gt;&lt;input name=&quot;noconfirmation&quot; type=&quot;checkbox&quot; id=&quot;noconfirmation&quot; value=&quot;1&quot; /&gt; &lt;label for=&quot;noconfirmation&quot;&gt;&lt;?php _e( 'Site administrators can add a user without sending the confirmation email.' ); ?&gt;&lt;/label&gt;&lt;/td&gt;
+        &lt;/tr&gt;
+        &lt;?php } ?&gt;
</ins><span class="cx"> &lt;/table&gt;
</span><span class="cx"> &lt;p class=&quot;submit&quot;&gt;
</span><span class="cx">         &lt;input name=&quot;adduser&quot; type=&quot;submit&quot; id=&quot;addusersub&quot; class=&quot;button-primary&quot; value=&quot;&lt;?php esc_attr_e('Add User') ?&gt;&quot; /&gt;
</span></span></pre></div>
<a id="trunkwpadminusersphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/users.php (12721 => 12722)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/users.php        2010-01-13 19:06:47 UTC (rev 12721)
+++ trunk/wp-admin/users.php        2010-01-14 02:02:19 UTC (rev 12722)
</span><span class="lines">@@ -98,10 +98,18 @@
</span><span class="cx">                 }
</span><span class="cx">                 switch($_REQUEST['delete_option']) {
</span><span class="cx">                 case 'delete':
</span><del>-                        wp_delete_user($id);
</del><ins>+                        if ( !is_multisite() ) {
+                                wp_delete_user($id);
+                        } else {
+                                remove_user_from_blog($id, $blog_id); // WPMU only remove user from blog
+                        }
</ins><span class="cx">                         break;
</span><span class="cx">                 case 'reassign':
</span><del>-                        wp_delete_user($id, $_REQUEST['reassign_user']);
</del><ins>+                        if ( !is_multisite() ) {
+                                wp_delete_user($id, $_REQUEST['reassign_user']);
+                        } else {
+                                remove_user_from_blog($id, $blog_id, $_REQUEST['reassign_user']);
+                        }
</ins><span class="cx">                         break;
</span><span class="cx">                 }
</span><span class="cx">                 ++$delete_count;
</span><span class="lines">@@ -153,7 +161,12 @@
</span><span class="cx">                         $go_delete = true;
</span><span class="cx">                 }
</span><span class="cx">         }
</span><del>-        $all_logins = $wpdb-&gt;get_results(&quot;SELECT ID, user_login FROM $wpdb-&gt;users ORDER BY user_login&quot;);
</del><ins>+        if ( !is_multisite() ) {
+                $all_logins = $wpdb-&gt;get_results(&quot;SELECT ID, user_login FROM $wpdb-&gt;users ORDER BY user_login&quot;);
+        } else {
+                // WPMU only searches users of current blog
+                $all_logins = $wpdb-&gt;get_results(&quot;SELECT ID, user_login FROM $wpdb-&gt;users, $wpdb-&gt;usermeta WHERE $wpdb-&gt;users.ID = $wpdb-&gt;usermeta.user_id AND meta_key = '&quot;.$wpdb-&gt;prefix.&quot;capabilities' ORDER BY user_login&quot;);
+        }
</ins><span class="cx">         $user_dropdown = '&lt;select name=&quot;reassign_user&quot;&gt;';
</span><span class="cx">         foreach ( (array) $all_logins as $login )
</span><span class="cx">                 if ( $login-&gt;ID == $current_user-&gt;ID || !in_array($login-&gt;ID, $userids) )
</span><span class="lines">@@ -239,7 +252,7 @@
</span><span class="cx"> 
</span><span class="cx"> &lt;div class=&quot;wrap&quot;&gt;
</span><span class="cx"> &lt;?php screen_icon(); ?&gt;
</span><del>-&lt;h2&gt;&lt;?php echo esc_html( $title ); ?&gt;  &lt;a href=&quot;user-new.php&quot; class=&quot;button add-new-h2&quot;&gt;&lt;?php echo esc_html_x('Add New', 'user'); ?&gt;&lt;/a&gt; &lt;?php
</del><ins>+&lt;h2&gt;&lt;?php echo esc_html( $title ); if ( !is_multisite() || get_site_option( 'add_new_users' ) ) { ?&gt;  &lt;a href=&quot;user-new.php&quot; class=&quot;button add-new-h2&quot;&gt;&lt;?php echo esc_html_x('Add New', 'user'); ?&gt;&lt;/a&gt;&lt;?php }
</ins><span class="cx"> if ( isset($_GET['usersearch']) &amp;&amp; $_GET['usersearch'] )
</span><span class="cx">         printf( '&lt;span class=&quot;subtitle&quot;&gt;' . __('Search results for &amp;#8220;%s&amp;#8221;') . '&lt;/span&gt;', esc_html( $_GET['usersearch'] ) ); ?&gt;
</span><span class="cx"> &lt;/h2&gt;
</span><span class="lines">@@ -385,6 +398,16 @@
</span><span class="cx"> &lt;/form&gt;
</span><span class="cx"> &lt;/div&gt;
</span><span class="cx"> 
</span><ins>+&lt;?php
+if ( is_multisite() ) {
+        foreach ( array('user_login' =&gt; 'user_login', 'first_name' =&gt; 'user_firstname', 'last_name' =&gt; 'user_lastname', 'email' =&gt; 'user_email', 'url' =&gt; 'user_uri', 'role' =&gt; 'user_role') as $formpost =&gt; $var ) {
+                $var = 'new_' . $var;
+                $$var = isset($_REQUEST[$formpost]) ? esc_attr(stripslashes($_REQUEST[$formpost])) : '';
+        }
+        unset($name);
+}
+?&gt;
+
</ins><span class="cx"> &lt;br class=&quot;clear&quot; /&gt;
</span><span class="cx"> &lt;?php
</span><span class="cx"> break;
</span></span></pre>
</div>
</div>

</body>
</html>