WordPress: Selectively Disable Plugin and Theme Editors, and Updates

Let’s face it, not all of us work in ideal situations. Some of us can create a site for a client, create only one administrator, and leave the client with lower privileges so that they are always at our mercy.

Other times you decide to throw up Multisite just so the client can technically be an administrator, but cannot update, add, or edit plugins and themes (much less update WordPress).

Admins, admins, everywhere!

The world I live in, everybody’s an admin. Sure, it’s not an ideal solution at all, but you have to work with what you have, right?

Today I created a snippet (with a lot of borrowed code) that will disable the plugin/theme editors, and will also disable updates from showing. All you have to do is throw it into your theme’s functions.php file.

I would guess that most of the clients, copywriters, etc, do not know the power that they hold when they are administrators. This snippet simply “hides” some of that power.

Disable by default, but allow enabling

Now if an admin really knows what they’re doing, they can “opt-in” to the plugin/theme editor and WordPress upgrade notices.

All the admin has to do is go to their user profile and select which options to opt-in on.

So in a nutshell, this snippet (by default) disables:

  • The ability to edit, delete, install, or update plugins.
  • The ability to edit, delete, install, or update themes.
  • The ability to upgrade WordPress. All notices are hidden.
Administrator Opt-in Options
Administrator Opt-in Options

Here be the code!

View it on GitHub or browse below.

<?php
//Tested in a theme's functions.php, but not in a plugin
//Allow overriding of editor
class opubco_user_optin {
public function __construct() {
add_action( 'personal_options', array( &$this, 'add_interface' ) );
//User update action
add_action( 'edit_user_profile_update', array( &$this, 'save_user_profile' ) );
add_action( 'personal_options_update', array( &$this, 'save_user_profile' ) );
//Override caps
add_filter( 'map_meta_cap', array( &$this, 'map_meta_cap' ), 11, 4 );
}
public function map_meta_cap( $caps, $cap, $user_id, $args ) {
if ( $cap == 'edit_plugins' || $cap == 'install_plugins' || $cap == 'delete_plugins' ) {
if ( current_user_can( 'administrator' ) && 'on' == get_user_option( 'opubco_plugin_editor', $user_id ) ) {
return array();
} else {
return array( 'do_not_allow' );
}
}
if ( $cap == 'edit_themes' || $cap == 'install_themes' || $cap == 'delete_themes') {
if ( current_user_can( 'administrator' ) && 'on' == get_user_option( 'opubco_theme_editor', $user_id ) ) {
return array();
} else {
return array( 'do_not_allow' );
}
}
return $caps;
}
public function add_interface() {
if ( !current_user_can( 'administrator' ) ) return;
$user_id = $this->get_user_id();
?>
</table>
<h3>Administrator Opt-in</h3>
<table class="form-table">
<tr valign="top">
<th scope="row"><?php esc_html_e( "Allow Editors", "opubco" ); ?></th>
<td>
<input type="checkbox" name="opt-in-plugin-editor" id="opt-in-plugin-editor" value="on" <?php checked( 'on', get_user_option( 'opubco_plugin_editor', $user_id ) ); ?> /><label for="opt-in-plugin-editor"> Allow plugin editor?</label>
<br /><br />
<input type="checkbox" name="opt-in-theme-editor" id="opt-in-theme-editor" value="on" <?php checked( 'on', get_user_option( 'opubco_theme_editor', $user_id ) ); ?> /><label for="opt-in-theme-editor"> Allow theme editor?</label>
</td>
</tr>
<tr valign="top">
<th scope="row"><?php esc_html_e( "WordPress Updates", "opubco" ); ?></th>
<td>
<input type="checkbox" name="opt-in-updates" id="opt-in-updates" value="on" <?php checked( 'on', get_user_option( 'opubco_wordpress_updates', $user_id ) ); ?> /><label for="opt-in-updates"> Show WordPress updates?</label>
</td>
</tr>
</table>
<?php
} //end add_interface
/**
* get_user_id
*
* Gets a user ID for the user
*
*@return int user_id
*
@return int post_id
*/
private function get_user_id() {
//Get user ID
$user_id = isset( $_GET[ 'user_id' ] ) ? absint( $_GET[ 'user_id' ] ) : 0;
if ( $user_id == 0 && IS_PROFILE_PAGE ) {
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
}
return $user_id;
} //end get_user_id
public function save_user_profile( $user_id ) {
check_admin_referer( 'update-user_' . $user_id );
if ( !current_user_can( 'administrator' ) ) return;
$user_meta = array();
$user_meta[ 'opubco_plugin_editor' ] = isset( $_POST[ 'opt-in-plugin-editor' ] ) ? 'on' : 'off';
$user_meta[ 'opubco_theme_editor' ] = isset( $_POST[ 'opt-in-theme-editor' ] ) ? 'on' : 'off';
$user_meta[ 'opubco_wordpress_updates' ] = isset( $_POST[ 'opt-in-updates' ] ) ? 'on' : 'off';
foreach( $user_meta as $meta_key => $meta_value ) {
update_user_option( $user_id, $meta_key, $meta_value );
}
}
}
//From https://wordpress.org/plugins/disable-wordpress-updates/
class opubco_disable_updates {
/**
* The OS_Disable_WordPress_Updates class constructor
* initializing required stuff for the plugin
*
* PHP 5 Constructor
*
* @since 1.3
* @author scripts@schloebe.de
*/
function __construct() {
if ( current_user_can( 'administrator' ) ) {
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
if ( 'on' == get_user_option( 'opubco_wordpress_updates', $user_id ) ) {
return;
}
}
add_action('admin_init', array(&$this, 'admin_init'));
/*
* Disable Theme Updates
* 2.8 to 3.0
*/
add_filter( 'pre_transient_update_themes', array($this, 'last_checked_now') );
/*
* 3.0
*/
add_filter( 'pre_site_transient_update_themes', array($this, 'last_checked_now') );
/*
* Disable Plugin Updates
* 2.8 to 3.0
*/
add_action( 'pre_transient_update_plugins', array(&$this, 'last_checked_now') );
/*
* 3.0
*/
add_filter( 'pre_site_transient_update_plugins', array($this, 'last_checked_now') );
/*
* Disable Core Updates
* 2.8 to 3.0
*/
add_filter( 'pre_transient_update_core', array($this, 'last_checked_now') );
/*
* 3.0
*/
add_filter( 'pre_site_transient_update_core', array($this, 'last_checked_now') );
/*
* Disable All Automatic Updates
* 3.7+
*
* @author sLa NGjI's @ slangji.wordpress.com
*/
add_filter( 'auto_update_translation', '__return_false' );
add_filter( 'automatic_updater_disabled', '__return_true' );
add_filter( 'allow_minor_auto_core_updates', '__return_false' );
add_filter( 'allow_major_auto_core_updates', '__return_false' );
add_filter( 'allow_dev_auto_core_updates', '__return_false' );
add_filter( 'auto_update_core', '__return_false' );
add_filter( 'wp_auto_update_core', '__return_false' );
add_filter( 'auto_core_update_send_email', '__return_false' );
add_filter( 'send_core_update_notification_email', '__return_false' );
add_filter( 'auto_update_plugin', '__return_false' );
add_filter( 'auto_update_theme', '__return_false' );
add_filter( 'automatic_updates_send_debug_email', '__return_false' );
add_filter( 'automatic_updates_is_vcs_checkout', '__return_true' );
}
/**
* The OS_Disable_WordPress_Updates class constructor
* initializing required stuff for the plugin
*
* PHP 4 Compatible Constructor
*
* @since 1.3
* @author scripts@schloebe.de
*/
function opubco_disable_updates() {
$this->__construct();
}
/**
* Initialize and load the plugin stuff
*
* @since 1.3
* @author scripts@schloebe.de
*/
function admin_init() {
if ( !function_exists("remove_action") ) return;
/*
* Disable Theme Updates
* 2.8 to 3.0
*/
remove_action( 'load-themes.php', 'wp_update_themes' );
remove_action( 'load-update.php', 'wp_update_themes' );
remove_action( 'admin_init', '_maybe_update_themes' );
remove_action( 'wp_update_themes', 'wp_update_themes' );
wp_clear_scheduled_hook( 'wp_update_themes' );
/*
* 3.0
*/
remove_action( 'load-update-core.php', 'wp_update_themes' );
wp_clear_scheduled_hook( 'wp_update_themes' );
/*
* Disable Plugin Updates
* 2.8 to 3.0
*/
remove_action( 'load-plugins.php', 'wp_update_plugins' );
remove_action( 'load-update.php', 'wp_update_plugins' );
remove_action( 'admin_init', '_maybe_update_plugins' );
remove_action( 'wp_update_plugins', 'wp_update_plugins' );
wp_clear_scheduled_hook( 'wp_update_plugins' );
/*
* 3.0
*/
remove_action( 'load-update-core.php', 'wp_update_plugins' );
wp_clear_scheduled_hook( 'wp_update_plugins' );
/*
* Disable Core Updates
* 2.8 to 3.0
*/
remove_action( 'wp_version_check', 'wp_version_check' );
remove_action( 'admin_init', '_maybe_update_core' );
wp_clear_scheduled_hook( 'wp_version_check' );
/*
* 3.0
*/
wp_clear_scheduled_hook( 'wp_version_check' );
/*
* 3.7+
*/
remove_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
remove_action( 'admin_init', 'wp_maybe_auto_update' );
remove_action( 'admin_init', 'wp_auto_update_core' );
wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
}
/**
* Get version check info
*
* @since 1.3.1
* @author flynsarmy (props & kudos!)
* @link http://wordpress.org/support/topic/patch-incorrect-disabling-of-updates
*/
public function last_checked_now( $transient ) {
include ABSPATH . WPINC . '/version.php';
$current = new stdClass;
$current->updates = array();
$current->version_checked = $wp_version;
$current->last_checked = time();
return $current;
}
}
new opubco_user_optin();
new opubco_disable_updates();

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top