4

I am trying to figure out how to remove settings I don't want my multisite admins to be able to change. In Settings->General I want to remove/hide these options (together with the text):

  • Tagline
  • Site Language
  • Date Format
  • Time Format
  • Week Starts On

I would like to do this with PHP, if there is something I can hook into to unset them? Using CSS i know it is possible. But CSS makes them reachable through browser dev settings.

Any idea how to do this?

1 Answer 1

3

Unfortunately, the html for those fields is hard-coded into the wp-admin/options-general.php file and there are no filters to keep them from being displayed.

The next-best thing is probably to disable them. Here's how I'd approach it:

Step 1: Adding a bit of js/jQuery to the general options page that will target the inputs/selects you want to disable and add the disabled attribute to them.

PHP:

add_action( 'admin_enqueue_scripts', 'wpse_maybe_add_custom_disable_fields_js' );
function wpse_maybe_add_custom_disable_fields_js() {
    if ( 'options-general' == get_current_screen()->id && is_multisite() && ! current_user_can( 'manage_network_options' ) ) {
        wp_enqueue_script( 'wpse_custom_disable_fields', 'path/to/disabler_script.js', array( 'jquery' ), false, true );
    }
}

Where in the above you replace 'path/to/disabler_script.js` with the correct path to the following file:

JS:

(function ($) {
    var fieldsIds = [
        'blogdescription',
        'WPLANG',
        'timezone_string',
        'date_format_custom_radio',
        'date_format_custom',
        'time_format_custom_radio',
        'time_format_custom',
        'start_of_week'
    ];

    $(document).ready(function () {
        fieldsIds.forEach(function (el) {
            $('#' + el).attr('disabled', 'disabled');
        });

        var radios = $('input[name="date_format"], input[name="time_format"]');
        $.each(radios, function (index, el ) {
            $(el).attr('disabled', 'diabled');
        });

    });
})(jQuery);

So far, we've made it hard for a "creative" admin to enter things into those fields, but they still could hack it into the browser. So, Step 2, we need to tie things down on the server end. Here, WP gives us a little help, because those setttings are all white-listed in the options processing, and we do have a filter to un-whitelist them:

PHP:

add_filter( 'whitelist_options', 'wpse_maybe_remove_settings_from_whitelist' );
function wpse_maybe_remove_settings_from_whitelist( array $whitelist_options ) {
    if ( is_multisite() && ! current_user_can( 'manage_network_options' ) ) {
        $whitelist_options['general'] = array( 'blogname', 'new_admin_email' );
    }
    return $whitelist_options;
}

Now, when the general settings form is returned, only the whitelisted options will be processed, even when other options have been hacked in and submitted.

3
  • Looks like you beat me do it regading the whitelist options ;) I will remove my answer.
    – birgire
    Jun 10, 2018 at 22:31
  • @birgire I'd have been happy to see your approach as well!
    – Caspar
    Jun 10, 2018 at 22:35
  • I filtered out the white-listed options instead of overriding that array, and suggested CSS instead of JS :-) i first tested unregister_setting() but that seems to only work on new options added by plugins.
    – birgire
    Jun 10, 2018 at 22:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.