Clean up plugins.php with regards to recently edited files, deactivations, and the network admin. see #20468, #20104.

* Limit recently_activated to the site dashboard, and properly remove bulk-activated plugins from the array.
 * Remove code used from before the network admin, such as the unused 'network' plugin_status.
 * Don't try to deactivate a plugin already deactivated.
 * Use more specific caps (manage_network_plugins) rather than is_super_admin().



git-svn-id: http://svn.automattic.com/wordpress/trunk@20525 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
nacin 2012-04-19 03:41:29 +00:00
parent abd8d6a4c2
commit c23bf21079
4 changed files with 77 additions and 67 deletions

View File

@ -13,7 +13,7 @@ class WP_Plugins_List_Table extends WP_List_Table {
global $status, $page; global $status, $page;
$status = 'all'; $status = 'all';
if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'active', 'inactive', 'recently_activated', 'upgrade', 'network', 'mustuse', 'dropins', 'search' ) ) ) if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'active', 'inactive', 'recently_activated', 'upgrade', 'mustuse', 'dropins', 'search' ) ) )
$status = $_REQUEST['plugin_status']; $status = $_REQUEST['plugin_status'];
if ( isset($_REQUEST['s']) ) if ( isset($_REQUEST['s']) )
@ -78,23 +78,21 @@ class WP_Plugins_List_Table extends WP_List_Table {
set_transient( 'plugin_slugs', array_keys( $plugins['all'] ), 86400 ); set_transient( 'plugin_slugs', array_keys( $plugins['all'] ), 86400 );
$recently_activated = get_option( 'recently_activated', array() ); if ( ! $screen->is_network ) {
$recently_activated = get_option( 'recently_activated', array() );
$one_week = 7*24*60*60; $one_week = 7*24*60*60;
foreach ( $recently_activated as $key => $time ) foreach ( $recently_activated as $key => $time )
if ( $time + $one_week < time() ) if ( $time + $one_week < time() )
unset( $recently_activated[$key] ); unset( $recently_activated[$key] );
update_option( 'recently_activated', $recently_activated ); update_option( 'recently_activated', $recently_activated );
}
foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) { foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) {
// Filter into individual sections // Filter into individual sections
if ( is_multisite() && is_network_only_plugin( $plugin_file ) && !$screen->is_network ) { if ( ! $screen->is_network && is_plugin_active_for_network( $plugin_file ) ) {
unset( $plugins['all'][ $plugin_file] );
} elseif ( is_plugin_active_for_network($plugin_file) && !$screen->is_network ) {
unset( $plugins['all'][ $plugin_file ] ); unset( $plugins['all'][ $plugin_file ] );
} elseif ( is_multisite() && is_network_only_plugin( $plugin_file ) && !current_user_can( 'manage_network_plugins' ) ) { } elseif ( ( ! $screen->is_network && is_plugin_active( $plugin_file ) )
$plugins['network'][ $plugin_file ] = $plugin_data;
} elseif ( ( !$screen->is_network && is_plugin_active( $plugin_file ) )
|| ( $screen->is_network && is_plugin_active_for_network( $plugin_file ) ) ) { || ( $screen->is_network && is_plugin_active_for_network( $plugin_file ) ) ) {
$plugins['active'][ $plugin_file ] = $plugin_data; $plugins['active'][ $plugin_file ] = $plugin_data;
} else { } else {
@ -215,9 +213,6 @@ class WP_Plugins_List_Table extends WP_List_Table {
case 'inactive': case 'inactive':
$text = _n( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', $count ); $text = _n( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', $count );
break; break;
case 'network':
$text = _n( 'Network <span class="count">(%s)</span>', 'Network <span class="count">(%s)</span>', $count );
break;
case 'mustuse': case 'mustuse':
$text = _n( 'Must-Use <span class="count">(%s)</span>', 'Must-Use <span class="count">(%s)</span>', $count ); $text = _n( 'Must-Use <span class="count">(%s)</span>', 'Must-Use <span class="count">(%s)</span>', $count );
break; break;
@ -248,10 +243,8 @@ class WP_Plugins_List_Table extends WP_List_Table {
$screen = get_current_screen(); $screen = get_current_screen();
if ( 'active' != $status ) { if ( 'active' != $status )
$action = $screen->is_network ? 'network-activate-selected' : 'activate-selected'; $actions['activate-selected'] = $screen->is_network ? __( 'Network Activate' ) : __( 'Activate' );
$actions[ $action ] = $screen->is_network ? __( 'Network Activate' ) : __( 'Activate' );
}
if ( 'inactive' != $status && 'recent' != $status ) if ( 'inactive' != $status && 'recent' != $status )
$actions['deactivate-selected'] = $screen->is_network ? __( 'Network Deactivate' ) : __( 'Deactivate' ); $actions['deactivate-selected'] = $screen->is_network ? __( 'Network Deactivate' ) : __( 'Deactivate' );
@ -283,7 +276,9 @@ class WP_Plugins_List_Table extends WP_List_Table {
echo '<div class="alignleft actions">'; echo '<div class="alignleft actions">';
if ( 'recently_activated' == $status ) $screen = get_current_screen();
if ( ! $screen->is_network && 'recently_activated' == $status )
submit_button( __( 'Clear List' ), 'secondary', 'clear-recent-list', false ); submit_button( __( 'Clear List' ), 'secondary', 'clear-recent-list', false );
elseif ( 'top' == $which && 'mustuse' == $status ) elseif ( 'top' == $which && 'mustuse' == $status )
echo '<p>' . sprintf( __( 'Files in the <code>%s</code> directory are executed automatically.' ), str_replace( ABSPATH, '/', WPMU_PLUGIN_DIR ) ) . '</p>'; echo '<p>' . sprintf( __( 'Files in the <code>%s</code> directory are executed automatically.' ), str_replace( ABSPATH, '/', WPMU_PLUGIN_DIR ) ) . '</p>';
@ -321,9 +316,8 @@ class WP_Plugins_List_Table extends WP_List_Table {
// preorder // preorder
$actions = array( $actions = array(
'network_deactivate' => '', 'deactivate' => '', 'deactivate' => '',
'network_only' => '', 'activate' => '', 'activate' => '',
'network_activate' => '',
'edit' => '', 'edit' => '',
'delete' => '', 'delete' => '',
); );
@ -348,22 +342,18 @@ class WP_Plugins_List_Table extends WP_List_Table {
if ( $plugin_data['Description'] ) if ( $plugin_data['Description'] )
$description .= '<p>' . $plugin_data['Description'] . '</p>'; $description .= '<p>' . $plugin_data['Description'] . '</p>';
} else { } else {
$is_active_for_network = is_plugin_active_for_network($plugin_file);
if ( $screen->is_network ) if ( $screen->is_network )
$is_active = $is_active_for_network; $is_active = is_plugin_active_for_network( $plugin_file );
else else
$is_active = is_plugin_active( $plugin_file ); $is_active = is_plugin_active( $plugin_file );
if ( $is_active_for_network && !is_super_admin() && !$screen->is_network )
return;
if ( $screen->is_network ) { if ( $screen->is_network ) {
if ( $is_active_for_network ) { if ( $is_active ) {
if ( current_user_can( 'manage_network_plugins' ) ) if ( current_user_can( 'manage_network_plugins' ) )
$actions['network_deactivate'] = '<a href="' . wp_nonce_url('plugins.php?action=deactivate&amp;networkwide=1&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'deactivate-plugin_' . $plugin_file) . '" title="' . esc_attr__('Deactivate this plugin') . '">' . __('Network Deactivate') . '</a>'; $actions['deactivate'] = '<a href="' . wp_nonce_url('plugins.php?action=deactivate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'deactivate-plugin_' . $plugin_file) . '" title="' . esc_attr__('Deactivate this plugin') . '">' . __('Network Deactivate') . '</a>';
} else { } else {
if ( current_user_can( 'manage_network_plugins' ) ) if ( current_user_can( 'manage_network_plugins' ) )
$actions['network_activate'] = '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;networkwide=1&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'activate-plugin_' . $plugin_file) . '" title="' . esc_attr__('Activate this plugin for all sites in this network') . '" class="edit">' . __('Network Activate') . '</a>'; $actions['activate'] = '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'activate-plugin_' . $plugin_file) . '" title="' . esc_attr__('Activate this plugin for all sites in this network') . '" class="edit">' . __('Network Activate') . '</a>';
if ( current_user_can( 'delete_plugins' ) && ! is_plugin_active( $plugin_file ) ) if ( current_user_can( 'delete_plugins' ) && ! is_plugin_active( $plugin_file ) )
$actions['delete'] = '<a href="' . wp_nonce_url('plugins.php?action=delete-selected&amp;checked[]=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-plugins') . '" title="' . esc_attr__('Delete this plugin') . '" class="delete">' . __('Delete') . '</a>'; $actions['delete'] = '<a href="' . wp_nonce_url('plugins.php?action=delete-selected&amp;checked[]=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-plugins') . '" title="' . esc_attr__('Delete this plugin') . '" class="delete">' . __('Delete') . '</a>';
} }

View File

@ -572,9 +572,11 @@ function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silen
* @since 2.5.0 * @since 2.5.0
* *
* @param string|array $plugins Single plugin or list of plugins to deactivate. * @param string|array $plugins Single plugin or list of plugins to deactivate.
* @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
* A value of null (the default) will deactivate plugins for both the site and the network.
* @param bool $silent Prevent calling deactivation hooks. Default is false. * @param bool $silent Prevent calling deactivation hooks. Default is false.
*/ */
function deactivate_plugins( $plugins, $silent = false ) { function deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
if ( is_multisite() ) if ( is_multisite() )
$network_current = get_site_option( 'active_sitewide_plugins', array() ); $network_current = get_site_option( 'active_sitewide_plugins', array() );
$current = get_option( 'active_plugins', array() ); $current = get_option( 'active_plugins', array() );
@ -585,15 +587,19 @@ function deactivate_plugins( $plugins, $silent = false ) {
if ( ! is_plugin_active($plugin) ) if ( ! is_plugin_active($plugin) )
continue; continue;
$network_wide = is_plugin_active_for_network( $plugin ); $network_deactivating = false !== $network_wide && is_plugin_active_for_network( $plugin );
if ( ! $silent ) if ( ! $silent )
do_action( 'deactivate_plugin', $plugin, $network_wide ); do_action( 'deactivate_plugin', $plugin, $network_deactivating );
if ( $network_wide ) { if ( false !== $network_wide ) {
if ( ! is_plugin_active_for_network( $plugin ) )
continue;
$do_network = true; $do_network = true;
unset( $network_current[ $plugin ] ); unset( $network_current[ $plugin ] );
} else { }
if ( true !== $network_wide ) {
$key = array_search( $plugin, $current ); $key = array_search( $plugin, $current );
if ( false !== $key ) { if ( false !== $key ) {
$do_blog = true; $do_blog = true;
@ -602,8 +608,8 @@ function deactivate_plugins( $plugins, $silent = false ) {
} }
if ( ! $silent ) { if ( ! $silent ) {
do_action( 'deactivate_' . $plugin, $network_wide ); do_action( 'deactivate_' . $plugin, $network_deactivating );
do_action( 'deactivated_plugin', $plugin, $network_wide ); do_action( 'deactivated_plugin', $plugin, $network_deactivating );
} }
} }

View File

@ -65,7 +65,8 @@ case 'update':
if ( is_plugin_active($file) ) if ( is_plugin_active($file) )
deactivate_plugins($file, true); deactivate_plugins($file, true);
update_option('recently_activated', array($file => time()) + (array)get_option('recently_activated')); if ( ! is_network_admin() )
update_option( 'recently_activated', array( $file => time() ) + (array) get_option( 'recently_activated' ) );
wp_redirect(add_query_arg('_wpnonce', wp_create_nonce('edit-plugin-test_' . $file), "plugin-editor.php?file=$file&liveupdate=1&scrollto=$scrollto&networkwide=" . $network_wide)); wp_redirect(add_query_arg('_wpnonce', wp_create_nonce('edit-plugin-test_' . $file), "plugin-editor.php?file=$file&liveupdate=1&scrollto=$scrollto&networkwide=" . $network_wide));
exit; exit;

View File

@ -12,7 +12,7 @@ require_once('./admin.php');
if ( is_multisite() ) { if ( is_multisite() ) {
$menu_perms = get_site_option( 'menu_items', array() ); $menu_perms = get_site_option( 'menu_items', array() );
if ( empty( $menu_perms['plugins'] ) && ! is_super_admin() ) if ( empty( $menu_perms['plugins'] ) && ! current_user_can( 'manage_network_plugins' ) )
wp_die( __( 'Cheatin&#8217; uh?' ) ); wp_die( __( 'Cheatin&#8217; uh?' ) );
} }
@ -31,9 +31,6 @@ $s = isset($_REQUEST['s']) ? urlencode($_REQUEST['s']) : '';
$_SERVER['REQUEST_URI'] = remove_query_arg(array('error', 'deleted', 'activate', 'activate-multi', 'deactivate', 'deactivate-multi', '_error_nonce'), $_SERVER['REQUEST_URI']); $_SERVER['REQUEST_URI'] = remove_query_arg(array('error', 'deleted', 'activate', 'activate-multi', 'deactivate', 'deactivate-multi', '_error_nonce'), $_SERVER['REQUEST_URI']);
if ( $action ) { if ( $action ) {
$network_wide = false;
if ( ( isset( $_GET['networkwide'] ) || 'network-activate-selected' == $action ) && is_multisite() && current_user_can( 'manage_network_plugins' ) )
$network_wide = true;
switch ( $action ) { switch ( $action ) {
case 'activate': case 'activate':
@ -42,7 +39,7 @@ if ( $action ) {
check_admin_referer('activate-plugin_' . $plugin); check_admin_referer('activate-plugin_' . $plugin);
$result = activate_plugin($plugin, self_admin_url('plugins.php?error=true&plugin=' . $plugin), $network_wide); $result = activate_plugin($plugin, self_admin_url('plugins.php?error=true&plugin=' . $plugin), is_network_admin() );
if ( is_wp_error( $result ) ) { if ( is_wp_error( $result ) ) {
if ( 'unexpected_output' == $result->get_error_code() ) { if ( 'unexpected_output' == $result->get_error_code() ) {
$redirect = self_admin_url('plugins.php?error=true&charsout=' . strlen($result->get_error_data()) . '&plugin=' . $plugin . "&plugin_status=$status&paged=$page&s=$s"); $redirect = self_admin_url('plugins.php?error=true&charsout=' . strlen($result->get_error_data()) . '&plugin=' . $plugin . "&plugin_status=$status&paged=$page&s=$s");
@ -53,11 +50,12 @@ if ( $action ) {
} }
} }
$recent = (array)get_option('recently_activated'); if ( ! is_network_admin() ) {
if ( isset($recent[ $plugin ]) ) { $recent = (array) get_option( 'recently_activated' );
unset($recent[ $plugin ]); unset( $recent[ $plugin ] );
update_option('recently_activated', $recent); update_option( 'recently_activated', $recent );
} }
if ( isset($_GET['from']) && 'import' == $_GET['from'] ) { if ( isset($_GET['from']) && 'import' == $_GET['from'] ) {
wp_redirect( self_admin_url("import.php?import=" . str_replace('-importer', '', dirname($plugin))) ); // overrides the ?error=true one above and redirects to the Imports page, stripping the -importer suffix wp_redirect( self_admin_url("import.php?import=" . str_replace('-importer', '', dirname($plugin))) ); // overrides the ?error=true one above and redirects to the Imports page, stripping the -importer suffix
} else { } else {
@ -66,7 +64,6 @@ if ( $action ) {
exit; exit;
break; break;
case 'activate-selected': case 'activate-selected':
case 'network-activate-selected':
if ( ! current_user_can('activate_plugins') ) if ( ! current_user_can('activate_plugins') )
wp_die(__('You do not have sufficient permissions to activate plugins for this site.')); wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
@ -75,7 +72,7 @@ if ( $action ) {
$plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array(); $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
// Only activate plugins which are not already active. // Only activate plugins which are not already active.
$check = $network_wide ? 'is_plugin_active_for_network' : 'is_plugin_active'; $check = is_network_admin() ? 'is_plugin_active_for_network' : 'is_plugin_active';
foreach ( $plugins as $i => $plugin ) foreach ( $plugins as $i => $plugin )
if ( $check( $plugin ) ) if ( $check( $plugin ) )
unset( $plugins[ $i ] ); unset( $plugins[ $i ] );
@ -85,14 +82,14 @@ if ( $action ) {
exit; exit;
} }
activate_plugins($plugins, self_admin_url('plugins.php?error=true'), $network_wide); activate_plugins($plugins, self_admin_url('plugins.php?error=true'), is_network_admin() );
$recent = (array)get_option('recently_activated'); if ( ! is_network_admin() ) {
foreach ( $plugins as $plugin => $time) $recent = (array) get_option('recently_activated' );
if ( isset($recent[ $plugin ]) ) foreach ( $plugins as $plugin )
unset($recent[ $plugin ]); unset( $recent[ $plugin ] );
update_option( 'recently_activated', $recent );
update_option('recently_activated', $recent); }
wp_redirect( self_admin_url("plugins.php?activate-multi=true&plugin_status=$status&paged=$page&s=$s") ); wp_redirect( self_admin_url("plugins.php?activate-multi=true&plugin_status=$status&paged=$page&s=$s") );
exit; exit;
@ -153,8 +150,15 @@ if ( $action ) {
wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.')); wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.'));
check_admin_referer('deactivate-plugin_' . $plugin); check_admin_referer('deactivate-plugin_' . $plugin);
deactivate_plugins($plugin);
update_option('recently_activated', array($plugin => time()) + (array)get_option('recently_activated')); if ( ! is_network_admin() && is_plugin_active_for_network() ) {
wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
exit;
}
deactivate_plugins( $plugin, false, is_network_admin() );
if ( ! is_network_admin() )
update_option( 'recently_activated', array( $plugin => time() ) + (array) get_option( 'recently_activated' ) );
if ( headers_sent() ) if ( headers_sent() )
echo "<meta http-equiv='refresh' content='" . esc_attr( "0;url=plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) . "' />"; echo "<meta http-equiv='refresh' content='" . esc_attr( "0;url=plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s" ) . "' />";
else else
@ -168,19 +172,27 @@ if ( $action ) {
check_admin_referer('bulk-plugins'); check_admin_referer('bulk-plugins');
$plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array(); $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
$plugins = array_filter($plugins, 'is_plugin_active'); //Do not deactivate plugins which are already deactivated. // Do not deactivate plugins which are already deactivated.
if ( is_network_admin() ) {
$plugins = array_filter( $plugins, 'is_plugin_active_for_network' );
} else {
$plugins = array_filter( $plugins, 'is_plugin_active' );
$plugins = array_diff( $plugins, array_filter( $plugins, 'is_plugin_active_for_network' ) );
}
if ( empty($plugins) ) { if ( empty($plugins) ) {
wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") ); wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") );
exit; exit;
} }
deactivate_plugins($plugins); deactivate_plugins( $plugins, false, is_network_admin() );
$deactivated = array(); if ( ! is_network_admin() ) {
foreach ( $plugins as $plugin ) $deactivated = array();
$deactivated[ $plugin ] = time(); foreach ( $plugins as $plugin )
$deactivated[ $plugin ] = time();
update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ) );
}
update_option('recently_activated', $deactivated + (array)get_option('recently_activated'));
wp_redirect( self_admin_url("plugins.php?deactivate-multi=true&plugin_status=$status&paged=$page&s=$s") ); wp_redirect( self_admin_url("plugins.php?deactivate-multi=true&plugin_status=$status&paged=$page&s=$s") );
exit; exit;
break; break;
@ -305,7 +317,8 @@ if ( $action ) {
exit; exit;
break; break;
case 'clear-recent-list': case 'clear-recent-list':
update_option('recently_activated', array()); if ( ! is_network_admin() )
update_option( 'recently_activated', array() );
break; break;
} }
} }