WordPress.org

Make WordPress Core

Ticket #14569: 15569.patch

File 15569.patch, 16.1 KB (added by rufein, 6 years ago)

Patch to disable some plugins in a multsite installation

  • src/wp-admin/includes/class-wp-plugins-list-table.php

     
    6767                        'recently_activated' => array(),
    6868                        'upgrade' => array(),
    6969                        'mustuse' => array(),
    70                         'dropins' => array()
     70                        'dropins' => array(),
     71                        'disable' => array(),
    7172                );
    7273
    7374                $screen = $this->screen;
     
    133134                        if ( is_multisite() && ! $screen->in_admin( 'network' ) && is_network_only_plugin( $plugin_file ) && ! is_plugin_active( $plugin_file ) ) {
    134135                                // On the non-network screen, filter out network-only plugins as long as they're not individually activated
    135136                                unset( $plugins['all'][ $plugin_file ] );
     137                        } elseif ( is_multisite() && ! $screen->in_admin( 'network' ) && ! is_plugin_enable_in_site($plugin_file) ){
     138                                // On the non-network screen, filter out disabled plugins to be shown
     139                                unset( $plugins['all'][ $plugin_file ] );
    136140                        } elseif ( ! $screen->in_admin( 'network' ) && is_plugin_active_for_network( $plugin_file ) ) {
    137141                                // On the non-network screen, filter out network activated plugins
    138142                                unset( $plugins['all'][ $plugin_file ] );
     
    395399                        'details' => '',
    396400                        'edit' => '',
    397401                        'delete' => '',
     402                        'disable_per_site' => '',
    398403                );
    399404
    400405                if ( 'mustuse' == $context ) {
     
    431436                                                $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>';
    432437                                        if ( current_user_can( 'delete_plugins' ) && ! is_plugin_active( $plugin_file ) )
    433438                                                $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>';
     439                                        // Disable plugins for some sites
     440                                        if ( current_user_can( 'manage_network_plugins' ) )
     441                                                $actions['disable_per_site'] = '<a href="' . wp_nonce_url(network_admin_url('plugin-settings.php?action=disable_per_site&amp;plugin=' . $plugin_file . '&amp;paged=' . $page . '&amp;s=' . $s, 'disable-plugin_' . $plugin_file), 'disable_plugins' ) . '" title="' . esc_attr__('Disable/Enable this plugin for some sites in this network') . '" class="disable">' . __('Disable/Enable plugin per site') . '</a>';
    434442                                }
    435443                        } else {
    436444                                if ( $is_active ) {
  • src/wp-admin/network/plugin-settings.php

     
     1<?php
     2/**
     3 * Multisite plugin settings administration panel.
     4 *
     5 * @package WordPress
     6 * @subpackage Multisite
     7 * @since -------------
     8 */
     9
     10/** Load WordPress Administration Bootstrap */
     11require_once( dirname( __FILE__ ) . '/admin.php' );
     12
     13if ( ! is_multisite() )
     14        wp_die( __( 'Multisite support is not enabled.' ) );
     15
     16if ( ! current_user_can( 'manage_network_plugins' ) )
     17        wp_die( __( 'You do not have permission to access this page.' ) );
     18
     19// Load parent class to create the class to display the sites
     20_get_list_table( 'WP_MS_Sites_List_Table' );
     21
     22/**
     23 * AD HOC class for displaying a sites list. The class take advantage of
     24 * the sites list table class and only redeclare some functions to adapt
     25 * the class.
     26 *
     27 */
     28class WP_MS_Plugin_Settings_List_Table extends WP_MS_Sites_List_Table {
     29
     30        public function __construct( $args = array() ) {
     31                parent::__construct( array(
     32                        'plural' => 'Plugin Settings',
     33                        'screen' => isset( $args['screen'] ) ? $args['screen'] : null )
     34                );
     35        }
     36
     37        public function ajax_user_can() {
     38                return current_user_can('manage_network_plugins');
     39        }
     40
     41        protected function get_bulk_actions() {
     42                $actions = array();
     43                if ( current_user_can( 'manage_network_plugins' ) ) {
     44                        $actions['enable'] = __( 'enable plugins' );
     45                        $actions['disable'] = __( 'disable plugins' );
     46                }
     47                return $actions;
     48        }
     49}
     50
     51
     52// Hooks declared in WP_MS_Sites_List_Table
     53add_filter('wpmu_blogs_columns', 'wp_network_plugin_settings_columns', 9999);             // Create a custom column
     54add_filter('manage_sites_action_links', 'wp_network_plugin_settings_actions', 9999, 3);   // Define new actions in Sites column
     55add_action('manage_sites_custom_column', 'wp_network_plugin_settings_row', 9999, 2);      // Content of custom column
     56
     57// Create the list class
     58$wp_list_table = new WP_MS_Plugin_Settings_List_Table();
     59$pagenum = $wp_list_table->get_pagenum();
     60
     61$title = __( 'Plugin Settings' );
     62$parent_file = 'plugin-settings.php';
     63
     64add_screen_option( 'per_page', array( 'label' => _x( 'Sites', 'sites per page (screen options)' ) ) );
     65
     66get_current_screen()->add_help_tab( array(
     67'id'      => 'overview',
     68'title'   => __('Overview'),
     69'content' =>
     70'<p>' . __('This is the main table of all sites on this network.') . '</p>' .
     71'<p>' . __('Hovering over each site reveals two options:') . '</p>' .
     72'<ul><li>' . __('Enable the plugin in a site (the site admin can activate or deactivate.)') . '</li>' .
     73'<li>' . __('Disable the plugin in a site (the plugin isn´t available in the selected site)') . '</li>' .
     74'</ul>' .
     75'<p>' . __('Clicking on bold headings can re-sort this table.') . '</p>'
     76) );
     77
     78/* Not exist official page
     79get_current_screen()->set_help_sidebar(
     80'<p><strong>' . __('For more information:') . '</strong></p>' .
     81'<p>' . __('<a href="http://codex.wordpress.org/Network_Admin_Sites_Screen" target="_blank">Documentation on Site Management</a>') . '</p>' .
     82'<p>' . __('<a href="https://wordpress.org/support/forum/multisite/" target="_blank">Support Forums</a>') . '</p>'
     83);
     84*/
     85
     86$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
     87$id = isset( $_REQUEST['id'] ) ? $_REQUEST['id'] : '';
     88$ids = empty($id) ? array() : array($id);
     89
     90$reportnotupd = isset( $_REQUEST['reportnotupd'] ) ? $_REQUEST['reportnotupd'] : array();  // Report with the not updated ids
     91$reportupd = isset( $_REQUEST['reportupd'] ) ? $_REQUEST['reportupd'] : array();
     92
     93if ( isset( $_GET['action'] ) ) {
     94       
     95        if ( 'confirm' === $_GET['action'] ) {
     96                check_admin_referer( 'confirm' );
     97       
     98                if ( ! headers_sent() ) {
     99                        nocache_headers();
     100                        header( 'Content-Type: text/html; charset=utf-8' );
     101                }
     102       
     103                require_once( ABSPATH . 'wp-admin/admin-header.php' );
     104                ?>
     105                                <div class="wrap">
     106                                        <h2><?php _e( 'Confirm your action' ); ?></h2>
     107                                        <?php $url = 'plugin-settings.php?action=' . esc_attr( $_GET['action2'] ); ?>
     108                                        <form action="<?php echo network_admin_url($url) ?>" method="post">
     109                                                <input type="hidden" name="action" value="<?php echo esc_attr( $_GET['action2'] ) ?>" />
     110                                                <input type="hidden" name="id" value="<?php echo esc_attr( $id ); ?>" />
     111                                                <input type="hidden" name="plugin" value="<?php echo esc_attr( $plugin ); ?>" />
     112                                                <input type="hidden" name="_wp_http_referer" value="<?php echo esc_attr( wp_get_referer() ); ?>" />
     113                                                <?php wp_nonce_field( $_GET['action2'], '_wpnonce', false ); ?>
     114                                                <p><?php echo esc_html( wp_unslash( $_GET['msg'] ) ); ?></p>
     115                                                <?php submit_button( __( 'Confirm' ), 'button' ); ?>
     116                                        </form>
     117                                </div>
     118                <?php
     119                require_once( ABSPATH . 'wp-admin/admin-footer.php' );
     120                exit();
     121        }
     122       
     123        $manage_actions = array( 'disable', 'enable' );
     124        if ( in_array( $_GET['action'], $manage_actions ) ) {
     125                $action = $_GET['action'];
     126                if ( 'allblogs' === $action )
     127                        $action = 'bulk-sites';
     128       
     129                check_admin_referer( $action );
     130        }
     131       
     132       
     133        $doaction = $_GET['action'];
     134       
     135        if ( 'allblogs' === $doaction ) {
     136                if ( ( isset( $_POST['action'] ) || isset( $_POST['action2'] ) ) && isset( $_POST['allblogs'] ) )
     137                        $doaction = $_POST['action'] != -1 ? $_POST['action'] : $_POST['action2'];
     138
     139                if ( ! current_user_can( 'manage_network_plugins' ) )
     140                        wp_die( __( 'You are not allowed to enable or disable plugins' ) );
     141
     142                $ids = (array) $_POST['allblogs'];
     143        }
     144       
     145        switch ( $doaction ) {
     146
     147                case 'disable':
     148                        if ( ! current_user_can( 'manage_network_plugins' ) )
     149                                wp_die( __( 'You do not have permission to access this page.' ) );
     150                       
     151                        if ( empty($plugin) || ! is_array($ids) )
     152                                break;
     153                       
     154                        foreach ( $ids as $id ) {
     155                       
     156                                $disable_plugins = get_blog_option($id, 'disable_plugins');
     157                                if(empty($disable_plugins))
     158                                        $disable_plugins = array();
     159                               
     160                                // Check duplicate plugin
     161                                if ( ! in_array( $plugin , $disable_plugins) ){
     162                                        $disable_plugins[] = $plugin;
     163                                }
     164                               
     165                                // Check if it is active. If true, report it and not updated
     166                                if ( wp_network_is_plugin_active($id, $plugin) ){
     167                                        $reportnotupd[] = $id;
     168                                        continue;
     169                                }
     170                               
     171                                $updated_option = update_blog_option( $id, 'disable_plugins', $disable_plugins );
     172                                if ( ! $updated_option )
     173                                        add_blog_option( $id, 'disable_plugins', $disable_plugins );
     174                                else
     175                                        $reportupd[] = $id;     
     176                        }
     177                       
     178                        $updated_action = 'disable';
     179                        break;
     180               
     181                case 'enable':
     182                        if ( ! current_user_can( 'manage_network_plugins' ) )
     183                                wp_die( __( 'You do not have permission to access this page.' ) );
     184                               
     185                        if ( empty($plugin) || ! is_array($ids) )
     186                                break;
     187                       
     188                        foreach ( $ids as $id ) {               
     189                                $disable_plugins = get_blog_option($id, 'disable_plugins');
     190                                if ( in_array( $plugin , $disable_plugins) ){
     191                                       
     192                                        $disable_plugins_updated = array();
     193                                        foreach($disable_plugins as $pl){
     194                                                if ( $pl != $plugin)
     195                                                        $disable_plugins_updated[] = $pl;
     196                                        }
     197                                        $disable_plugins = $disable_plugins_updated;
     198                                }
     199                                       
     200                                $updated_option = update_blog_option($id, 'disable_plugins', $disable_plugins);
     201                                if ( ! $updated_option )
     202                                        add_blog_option( $id, 'disable_plugins', $disable_plugins );
     203                                else
     204                                        $reportupd[] = $id;     
     205                        }
     206               
     207                        $updated_action = 'enable';     
     208                        break;
     209        }
     210
     211        if ( empty( $updated_action ) && in_array( $_GET['action'], $manage_actions ) )
     212                $updated_action = $_GET['action'];
     213
     214        if ( ! empty( $updated_action ) ) {
     215                wp_safe_redirect( add_query_arg( array( 'updated' => $updated_action, 'reportupd' => $reportupd, 'reportnotupd' => $reportnotupd ), wp_get_referer() ) );
     216                exit();
     217        }
     218}
     219
     220$msg = '';
     221if ( isset( $_GET['updated'] ) ) {
     222       
     223        if ( !empty($reportupd) ){
     224                $msg .= '<div class="updated"><ul>';
     225                foreach ($reportupd as $id){
     226                        switch_to_blog( $id );
     227                        $msg .= '<li>' . sprintf( __ ('Settings saved in: <strong> %1$s </strong>' ), get_option( 'blogname' ) ) . '</li>';
     228                        restore_current_blog();
     229                }
     230                $msg .= '</ul></div>';
     231        }
     232       
     233        if ( !empty($reportnotupd) ){
     234                $msg .= '<div class="error"><ul>';
     235                foreach ($reportnotupd as $id){
     236                        switch_to_blog( $id );
     237                        $msg .= '<li>' . sprintf( __ ('Not updated in <strong> %1$s </strong> because the plugin is <strong>Active</strong>' ), get_option( 'blogname' ) ) . '</li>';
     238                        restore_current_blog();
     239                }
     240                $msg .= '</ul></div>';
     241        }
     242       
     243}
     244
     245$wp_list_table->prepare_items();
     246
     247require_once( ABSPATH . 'wp-admin/admin-header.php' );
     248?>
     249
     250<div class="wrap">
     251<h2><?php printf(__( 'Plugin settings: %s' ), $plugin ) ?>
     252
     253<?php if ( isset( $_REQUEST['s'] ) && $_REQUEST['s'] ) {
     254        printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;' ) . '</span>', esc_html( $s ) );
     255} ?>
     256</h2>
     257
     258<?php echo $msg; ?>
     259
     260<form action="" method="get" id="ms-search">
     261<?php $wp_list_table->search_box( __( 'Search Sites' ), 'site' ); ?>
     262<input type="hidden" name="action" value="blogs" />
     263</form>
     264
     265<form id="form-site-list" action="plugin-settings.php?action=allblogs&amp;plugin=<?php echo $plugin ?>" method="post">
     266        <?php $wp_list_table->display(); ?>
     267</form>
     268</div>
     269<?php
     270
     271require_once( ABSPATH . 'wp-admin/admin-footer.php' ); ?>
     272 No newline at end of file
  • src/wp-includes/ms-functions.php

     
    24342434
    24352435        return $site_results;
    24362436}
     2437
     2438/**
     2439 * Define columns for the plugins settings page in network.
     2440 *
     2441 * This hook is fired on wpmu_blogs_columns when the plugin settings page is requested.
     2442 *
     2443 * @return array An array of defined columns with their respective titles.
     2444 */
     2445function wp_network_plugin_settings_columns( $columns ){
     2446
     2447        $new_columns['cb'] = $columns['cb'];                            //Checkbox
     2448        $new_columns['blogname'] = $columns['blogname'];        // Path
     2449        $new_columns['disable_plugins'] = __('Enable or Disable');
     2450        $new_columns['is_active'] =  __('Is Active The Plugin');
     2451        $new_columns['lastupdated'] = $columns['lastupdated'];
     2452        $new_columns['registered'] = $columns['registered'];
     2453        $new_columns['users'] = $columns['users'];
     2454
     2455        return $new_columns;
     2456}
     2457
     2458/**
     2459 * Define actions to manage plugins in network.
     2460 *
     2461 * This hook is fired on manage_sites_action_links when the plugin settings page is requested.
     2462 *
     2463 * @param array         $actions
     2464 * @param int           $blog_id
     2465 * @param string        $blogname
     2466 *
     2467 * @return array Array of actions
     2468 */
     2469function wp_network_plugin_settings_actions( $actions, $blog_id, $blogname ){
     2470
     2471        // The main blog hasn't got actions
     2472        if($blog_id <= 1)
     2473                return;
     2474
     2475        $plugin_name = $_REQUEST['plugin'];
     2476
     2477        $disable_plugins = get_blog_option($blog_id, 'disable_plugins', array() );
     2478
     2479        $action = 'disable';
     2480        $msg =  __( 'You are about to disable the plugin in the site %s' );
     2481        if( in_array( $plugin_name, $disable_plugins) ){
     2482                $action = 'enable';
     2483                $msg = __( 'You are about to enable the plugin in the site %s' );
     2484        }
     2485         
     2486        $url = 'plugin-settings.php?action=confirm&amp;action2=' . $action . '&amp;id=' . $blog_id . '&amp;plugin='. $plugin_name . '&amp;msg=' . urlencode( sprintf( $msg, $blogname ) );
     2487        $new_actions[$action] =  '<span class="enable">';
     2488        $new_actions[$action] .= '<a href="' . esc_url( wp_nonce_url( network_admin_url( $url ), 'confirm' ) ) . '">' . __( $action ) . '</a>';
     2489        $new_actions[$action] .= '</span>';
     2490
     2491        return $new_actions;
     2492}
     2493
     2494/**
     2495 * Print the result of every row in columns of plugin settings page.
     2496 *
     2497 * This hook is fired on manage_sites_custom_column.
     2498 *
     2499 * @param string         $column_name
     2500 * @param int            $blog_id
     2501 */
     2502function wp_network_plugin_settings_row($column_name, $blog_id){
     2503
     2504        // The main blog hasn't got access
     2505        if( $blog_id <= 1 ) {
     2506                echo '<strong>' . __("Never") . '</strong>';
     2507                return ;
     2508        }
     2509
     2510        $enable_classes = 'background-color: #7ad03a; border-radius: 10px; color: #fff; display: inline-block;  font-weight: 600;  line-height: 17px; padding: 4px;';
     2511        $disable_classes = 'background-color: #d54e21; border-radius: 10px; color: #fff; display: inline-block;  font-weight: 600;  line-height: 17px; padding: 4px;';
     2512
     2513        $plugin_name = $_REQUEST['plugin'];
     2514
     2515        if ($column_name == 'disable_plugins'){
     2516
     2517                $disable_plugins = get_blog_option($blog_id, 'disable_plugins', array() );
     2518                if ( !in_array( $plugin_name, $disable_plugins) ){
     2519                        echo '<span style="' . $enable_classes . '">' . __("Enable") . '</span>';
     2520                }else{
     2521                        echo '<span style="' . $disable_classes . '">' .  __("Disable") . '</span>';
     2522                }
     2523        }
     2524
     2525        if ($column_name == 'is_active'){
     2526                if ( wp_network_is_plugin_active($blog_id, $plugin_name) ){
     2527                        echo '<span style="' . $enable_classes . '">' . __("Active") . '</span>';
     2528                }else{
     2529                        echo '<span style="' . $disable_classes . '">' . __("Inactive") . '</span>';
     2530                }
     2531        }
     2532
     2533}
     2534
     2535/**
     2536 * If a plugin is active in a site or blog in multisite.
     2537 *
     2538 * @param  int          $blog_id
     2539 * @param  string       $plugin_name
     2540 * @return boolean
     2541 */
     2542function wp_network_is_plugin_active($blog_id, $plugin_name){
     2543        switch_to_blog($blog_id);
     2544        $is_active = is_plugin_active($plugin_name);
     2545        restore_current_blog();
     2546        return $is_active;
     2547}
     2548
     2549function is_plugin_enable_in_site( $plugin_name , $blog_id = 0){
     2550       
     2551        if($blog_id == 0){
     2552                $blog_id = $GLOBALS['blog_id'];
     2553        }
     2554       
     2555        $disable_plugins = get_blog_option($blog_id, 'disable_plugins', array() );
     2556        if ( in_array ($plugin_name, $disable_plugins) )
     2557                return false;
     2558        return true;
     2559}