diff --git a/wp-admin/plugins.php b/wp-admin/plugins.php index c56313863b..cc8bcff2c2 100644 --- a/wp-admin/plugins.php +++ b/wp-admin/plugins.php @@ -231,8 +231,10 @@ wp_enqueue_script('plugin-install'); add_thickbox(); $help = '

' . __('Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.') . '

'; +if ( !is_multisite() || is_super_admin() ) { $help .= '

' . sprintf(__('If something goes wrong with a plugin and you can’t use WordPress, delete or rename that file in the %s directory and it will be automatically deactivated.'), WP_PLUGIN_DIR) . '

'; $help .= '

' . sprintf(__('You can find additional plugins for your site by using the new Plugin Browser/Installer functionality or by browsing the WordPress Plugin Directory directly and installing manually. To manually install a plugin you generally just need to upload the plugin file into your %2$s directory. Once a plugin has been installed, you may activate it here.'), 'plugin-install.php', WP_PLUGIN_DIR) . '

'; +} add_contextual_help('plugins', $help); @@ -282,11 +284,11 @@ if ( !empty($invalid) )
-

+

$plugin_data) { $upgrade_plugins[ $plugin_file ] = $plugin_data; } +if ( is_multisite() && !is_super_admin() ) { + $upgrade_plugins = false; +} + $total_all_plugins = count($all_plugins); $total_inactive_plugins = count($inactive_plugins); $total_active_plugins = count($active_plugins); @@ -515,6 +521,8 @@ function print_plugin_actions($context, $field_name = 'action' ) {

+ +
diff --git a/wp-admin/themes.php b/wp-admin/themes.php index 641c9adf5f..6e53ece07c 100644 --- a/wp-admin/themes.php +++ b/wp-admin/themes.php @@ -12,6 +12,30 @@ require_once('admin.php'); if ( !current_user_can('switch_themes') ) wp_die( __( 'Cheatin’ uh?' ) ); +if ( is_multisite() ) { + $themes = get_themes(); + $ct = current_theme_info(); + $allowed_themes = apply_filters("allowed_themes", 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[ "h3" ] ); + + if( isset( $allowed_themes[ wp_specialchars( $ct->stylesheet ) ] ) == false ) + $allowed_themes[ wp_specialchars( $ct->stylesheet ) ] = true; + + reset( $themes ); + foreach( $themes as $key => $theme ) { + if( isset( $allowed_themes[ wp_specialchars( $theme[ 'Stylesheet' ] ) ] ) == false ) { + unset( $themes[ $key ] ); + } + } + reset( $themes ); +} if ( isset($_GET['action']) ) { if ( 'activate' == $_GET['action'] ) { check_admin_referer('switch-theme_' . $_GET['template']); @@ -32,7 +56,7 @@ $title = __('Manage Themes'); $parent_file = 'themes.php'; $help = '

' . __('Themes give your WordPress style. Once a theme is installed, you may preview it, activate it or deactivate it here.') . '

'; -if ( current_user_can('install_themes') ) { +if ( ( !is_multisite() && current_user_can('install_themes') ) || is_super_admin() ) { $help .= '

' . sprintf(__('You can find additional themes for your site by using the new Theme Browser/Installer functionality or by browsing the WordPress Theme Directory directly and installing manually. To install a theme manually, upload its ZIP archive with the new uploader or copy its folder via FTP into your wp-content/themes directory.'), 'theme-install.php', 'theme-install.php?tab=upload' ) . '

'; $help .= '

' . __('Once a theme is uploaded, you should see it on this page.') . '

' ; } @@ -43,6 +67,9 @@ add_thickbox(); wp_enqueue_script( 'theme-preview' ); require_once('admin-header.php'); +if( is_multisite() && is_super_admin() ) { + ?>

Themes Admin page before they appear here.'); ?>

@@ -58,7 +85,8 @@ require_once('admin-header.php'); name]); @@ -97,6 +125,10 @@ $themes = array_slice( $themes, $start, $per_page ); */ function theme_update_available( $theme ) { static $themes_update; + + if ( is_multisite() && !is_super_admin() ) + return; + if ( !isset($themes_update) ) $themes_update = get_site_transient('update_themes'); @@ -127,7 +159,7 @@ function theme_update_available( $theme ) {
-

+

@@ -138,7 +170,7 @@ function theme_update_available( $theme ) { /* translators: 1: theme title, 2: theme version, 3: theme author */ printf(__('%1$s %2$s by %3$s'), $ct->title, $ct->version, $ct->author) ; ?>

description; ?>

-parent_theme) { ?> +parent_theme ) { ?>

%2$s. The stylesheet files are located in %3$s. %4$s uses templates from %5$s. Changes made to the templates will affect both themes.'), $ct->title, str_replace( WP_CONTENT_DIR, '', $ct->template_dir ), str_replace( WP_CONTENT_DIR, '', $ct->stylesheet_dir ), $ct->title, $ct->parent_theme); ?>

%2$s.'), $ct->title, str_replace( WP_CONTENT_DIR, '', $ct->template_dir ), str_replace( WP_CONTENT_DIR, '', $ct->stylesheet_dir ) ); ?>

@@ -217,7 +249,7 @@ foreach ( $cols as $col => $theme_name ) { $actions = array(); $actions[] = '' . __('Activate') . ''; $actions[] = '' . __('Preview') . ''; - if ( current_user_can('update_themes') ) + if ( ( !is_multisite() && current_user_can('update_themes') ) || is_super_admin() ) $actions[] = '' . __('Delete') . ''; $actions = apply_filters('theme_action_links', $actions, $themes[$theme_name]); @@ -233,7 +265,7 @@ foreach ( $cols as $col => $theme_name ) { printf(__('%1$s %2$s by %3$s'), $title, $version, $author) ; ?>

-

%2$s. The stylesheet files are located in %3$s. %4$s uses templates from %5$s. 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); ?>

@@ -266,10 +298,10 @@ foreach ( $cols as $col => $theme_name ) { -

+

diff --git a/wp-admin/upgrade.php b/wp-admin/upgrade.php index 6862407463..9e40bf9fee 100644 --- a/wp-admin/upgrade.php +++ b/wp-admin/upgrade.php @@ -86,6 +86,11 @@ switch ( $step ) : $backto = stripslashes( urldecode( $backto ) ); $backto = esc_url_raw( $backto ); $backto = wp_validate_redirect($backto, __get_option( 'home' ) . '/'); + if( $wpdb->get_row( "SELECT blog_id FROM {$wpdb->blog_versions} WHERE blog_id = '{$wpdb->blogid}'" ) ) { + $wpdb->query( "UPDATE {$wpdb->blog_versions} SET db_version = '{$wp_db_version}' WHERE blog_id = '{$wpdb->blogid}'" ); + } else { + $wpdb->query( "INSERT INTO {$wpdb->blog_versions} ( `blog_id` , `db_version` , `last_updated` ) VALUES ( '{$wpdb->blogid}', '{$wp_db_version}', NOW());" ); + } ?>

diff --git a/wp-admin/user-edit.php b/wp-admin/user-edit.php index f28e59aa3d..ec7e801881 100644 --- a/wp-admin/user-edit.php +++ b/wp-admin/user-edit.php @@ -60,6 +60,11 @@ function use_ssl_preference($user) { ID ) + wp_die( __( 'You do not have permission to edit this user.' ) ); + switch ($action) { case 'switchposts': @@ -81,7 +86,24 @@ if ( IS_PROFILE_PAGE ) else do_action('edit_user_profile_update', $user_id); -$errors = edit_user($user_id); +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->get_blog_prefix(); + if( $user_id != $current_user->ID ) { + $cap = $wpdb->get_var( "SELECT meta_value FROM {$wpdb->usermeta} WHERE user_id = '{$user_id}' AND meta_key = '{$blog_prefix}capabilities' AND meta_value = 'a:0:{}'" ); + if( null == $cap && $_POST[ 'role' ] == '' ) { + $_POST[ 'role' ] = 'contributor'; + $delete_role = true; + } + } + if ( !isset( $errors ) || ( isset( $errors ) && is_object( $errors ) && false == $errors->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' , '' ); +} if ( !is_wp_error( $errors ) ) { $redirect = (IS_PROFILE_PAGE ? "profile.php?" : "user-edit.php?user_id=$user_id&"). "updated=true"; diff --git a/wp-admin/user-new.php b/wp-admin/user-new.php index 9d143253b6..28cdba06cd 100644 --- a/wp-admin/user-new.php +++ b/wp-admin/user-new.php @@ -15,21 +15,89 @@ if ( !current_user_can('create_users') ) /** WordPress Registration API */ require_once( ABSPATH . WPINC . '/registration.php'); +if ( is_multisite() ) { + function admin_created_user_email( $text ) { + return sprintf( __( "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" ), 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 "[" . get_bloginfo('name') . "] Your blog invite"; + } +} + if ( isset($_REQUEST['action']) && 'adduser' == $_REQUEST['action'] ) { check_admin_referer('add-user'); if ( ! current_user_can('create_users') ) wp_die(__('You can’t create users.')); - $user_id = add_user(); + if ( !is_multisite() ) { + $user_id = add_user(); - if ( is_wp_error( $user_id ) ) { - $add_user_errors = $user_id; + 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) . '&update=add'; + wp_redirect( $redirect . '#user-' . $user_id ); + die(); + } } else { - $new_user_login = apply_filters('pre_user_login', sanitize_user(stripslashes($_REQUEST['user_login']), true)); - $redirect = 'users.php?usersearch='. urlencode($new_user_login) . '&update=add'; - wp_redirect( $redirect . '#user-' . $user_id ); - die(); + $user_login = preg_replace( "/\s+/", '', sanitize_user( $_REQUEST[ 'user_login' ], true ) ); + $user_details = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->users} WHERE user_login = %s AND user_email = %s", $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->user_login; + $user_id = $user_details->ID; + if( ($username != null && is_site_admin( $username ) == false ) && ( array_key_exists($blog_id, get_blogs_of_user($user_id)) ) ) { + $redirect = add_query_arg( array('update' => 'addexisting'), 'user-new.php' ); + } else { + if ( isset( $_POST[ 'noconfirmation' ] ) && is_site_admin() ) { + add_existing_user_to_blog( array( 'user_id' => $user_id, 'role' => $_REQUEST[ 'role' ] ) ); + $redirect = add_query_arg( array('update' => 'addnoconfirmation'), 'user-new.php' ); + } else { + $newuser_key = substr( md5( $user_id ), 0, 5 ); + add_option( 'new_user_' . $newuser_key, array( 'user_id' => $user_id, 'email' => $user_details->user_email, 'role' => $_REQUEST[ 'role' ] ) ); + $message = __("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"); + wp_mail( $new_user_email, sprintf( __( '[%s] Joining confirmation' ), get_option( 'blogname' ) ), sprintf($message, get_option('blogname'), site_url(), $_REQUEST[ 'role' ], site_url("/newbloguser/$newuser_key/"))); + $redirect = add_query_arg( array('update' => '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' ]->errors[ 'user_email_used' ] ); + if ( is_wp_error( $user_details[ 'errors' ] ) && !empty( $user_details[ 'errors' ]->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' ] ) && 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' => $wpdb->blogid, 'new_role' => $_REQUEST[ 'role' ] ) ); + if ( isset( $_POST[ 'noconfirmation' ] ) && is_site_admin() ) { + $key = $wpdb->get_var( $wpdb->prepare( "SELECT activation_key FROM {$wpdb->signups} WHERE user_login = %s AND user_email = %s", $new_user_login, $_REQUEST[ 'email' ] ) ); + wpmu_activate_signup( $key ); + $redirect = add_query_arg( array('update' => 'addnoconfirmation'), 'user-new.php' ); + } else { + $redirect = add_query_arg( array('update' => 'newuserconfimation'), 'user-new.php' ); + } + wp_redirect( $redirect ); + die(); + } + } } } @@ -42,6 +110,22 @@ wp_enqueue_script('password-strength-meter'); require_once ('admin-header.php'); +if ( is_multisite() ) { + switch( $_GET[ 'update' ] ) { + case "newuserconfimation": + $messages[] = '

' . __('Invitation email sent to new user. A confirmation link must be clicked before their account is created.') . '

'; + break; + case "add": + $messages[] = '

' . __('Invitation email sent to user. A confirmation link must be clicked for them to be added to your blog.') . '

'; + break; + case "addnoconfirmation": + $messages[] = '

' . __('User has been added to your blog.') . '

'; + break; + case "addexisting": + $messages[] = '

' . __('That user is already a member of this blog.') . '

'; + break; + } +} ?>
@@ -74,10 +158,15 @@ if ( ! empty($messages) ) {
' . sprintf(__('Users can register themselves or you can manually create users here.'), site_url('wp-register.php')) . '

'; else echo '

' . sprintf(__('Users cannot currently register themselves, but you can manually create users here.'), admin_url('options-general.php#users_can_register')) . '

'; +} else { + echo '

' . __( 'You can add new users to your blog in two ways:' ) . '

  1. ' . __( 'Enter the username and email address of an existing user on this site.' ) . '
  2. ' . __( '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.' ) . '

'; + echo '

' . __( '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.' ) . '

'; +} ?> @@ -92,6 +181,7 @@ foreach ( array('user_login' => 'login', 'first_name' => 'firstname', 'last_name $new_user_send_password = !$_POST || isset($_POST['send_password']); ?>
+ @@ -130,7 +220,16 @@ $new_user_send_password = !$_POST || isset($_POST['send_password']); - + + + + + + + + + + + + + + + + +

diff --git a/wp-admin/users.php b/wp-admin/users.php index 1c7f84ce5e..c75b963076 100644 --- a/wp-admin/users.php +++ b/wp-admin/users.php @@ -98,10 +98,18 @@ case 'dodelete': } switch($_REQUEST['delete_option']) { case 'delete': - wp_delete_user($id); + if ( !is_multisite() ) { + wp_delete_user($id); + } else { + remove_user_from_blog($id, $blog_id); // WPMU only remove user from blog + } break; case 'reassign': - wp_delete_user($id, $_REQUEST['reassign_user']); + if ( !is_multisite() ) { + wp_delete_user($id, $_REQUEST['reassign_user']); + } else { + remove_user_from_blog($id, $blog_id, $_REQUEST['reassign_user']); + } break; } ++$delete_count; @@ -153,7 +161,12 @@ case 'delete': $go_delete = true; } } - $all_logins = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users ORDER BY user_login"); + if ( !is_multisite() ) { + $all_logins = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users ORDER BY user_login"); + } else { + // WPMU only searches users of current blog + $all_logins = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users, $wpdb->usermeta WHERE $wpdb->users.ID = $wpdb->usermeta.user_id AND meta_key = '".$wpdb->prefix."capabilities' ORDER BY user_login"); + } $user_dropdown = '