4

does anybody know how to hook or filter the user-edit.php file so that an user's email address is disabled from editing akin to how the username is disabled ..??..

i can edit the core file (gasp) and include disabled="disabled" in the form and this works but i'm at a loss as to how to add the disable via hook or filter ..

i can also run a function like this that hides the email address via css

/* Change WordPress dashboard CSS */
function custom_admin_styles() {
echo '<style type="text/css">#email { display: none !important; }</style>';
}
add_action('admin_head', 'custom_admin_styles');

but that pulls out the whole email thus form looks funny and then i believe that with a DOM Editor like Firebug, one can still access that email field thus change it ... ugh ...

ideally, i would like to replace this entire user-edit.php code from this ->

<label for="email"><?php _e('E-mail'); ?> <span class="description"><?php _e('(required)'); ?></span></label></th><td><input type="text" name="email" id="email" value="<?php echo esc_attr($profileuser->user_email) ?>" disabled="disabled" class="regular-text" /> <span class="description"><?php _e('Emails cannot be changed.'); ?></span>

to something like this ->

<label for="email"><?php _e('E-mail'); ?> </label></th><td><?php echo esc_attr($profileuser->user_email) ?>" Please Contact Tech support to change your email

thanks in advance for any pointers you can share ... cordially, chuck scott

  • you can use JQuery .append to disable it but it's a hackish way – Bainternet Mar 10 '11 at 21:05
2

Dirty hack, feel free to modify.

Only admins or users with edit_users cap "can change" email, others can't.

Theme functions.php:

class Edit_Email {
    function start() {
        ob_start();
    }

    function footer() {
        $content = ob_get_contents();

        ob_end_clean();

        $this->replace( $content );

        echo $content;
    }

    function replace( &$content ) {
        $pattern = array(
            '/E-mail <span.+?<\/span>/',
            '/<input type="text"(.*?)value="(\\S+@\\S+\\.\\w+)[^>]*\/>/'
        );

        $replacement = array(
            'E-mail',
            '<input type="hidden"\1value="\2" /> \2 Please Contact Tech support to change your email.'
        );

        $content = preg_replace( $pattern, $replacement, $content );
    }
}

if ( ! current_user_can( 'edit_users' ) && ( $pagenow == 'profile.php' ) ) :
    $edit_email = new Edit_Email();
    $edit_email->start();

    add_action( 'admin_footer', array( &$edit_email, 'footer' ) );
endif;
| improve this answer | |
  • AVOID THIS ANSWER!. worst and wrongest solution, leading to security issues. html modifications are just nothing - the request should be blocked in backend! (even the strangest way to modify the html, while you could have just used css to hide with display:none) – T.Todua Apr 6 at 12:33
2

Not exact answer, but to prevent email change (actual change, not field edit) you could tweak around this action:

add_action( 'user_profile_update_errors', 'prevent_email_change', 10, 3 );

function prevent_email_change( $errors, $update, $user ) {

    $old = get_user_by('id', $user->ID);

    if( $user->user_email != $old->user_email   && (!current_user_can('create_users')) )
            $user->user_email = $old->user_email;
}
| improve this answer | |
  • Is there any other better function than the user_profile_update_errors? – Starx Oct 28 '15 at 16:52
  • Define better? Very old answer, I wouldn't remember on top of my head. :) – Rarst Oct 28 '15 at 16:54
  • By better I mean any other function that doesn't need to hook to errors action. But then I read the hooks list and it does execute before the changes to the user is committed so its fine I think. I take my comment back :) – Starx Oct 28 '15 at 18:13
  • You missed (!current_user_can('create_users'))... – T.Todua Feb 6 '16 at 8:54
  • 1
    For those who are also looking for a WooCommerce action hook, there is one: do_action_ref_array( 'woocommerce_save_account_details_errors', array( &$errors, &$user ) ); – Rens Tillmann Apr 10 '19 at 20:42
2

In addition to Rarst's answer:

To prevent email change server side

add_action( 'user_profile_update_errors', 'prevent_email_change', 10, 3 );

function prevent_email_change( $errors, $update, $user ) {

    $old = get_user_by('id', $user->ID);

    if( $user->user_email != $old->user_email   && (!current_user_can('create_users')) )
            $user->user_email = $old->user_email;
}

To disable WordPress user email profile fields

add_action('admin_init', 'user_profile_fields_disable');

function user_profile_fields_disable() {

    global $pagenow;

    // apply only to user profile or user edit pages
    if ($pagenow!=='profile.php' && $pagenow!=='user-edit.php') {
        return;
    }

    // do not change anything for the administrator
    if (current_user_can('administrator')) {
        return;
    }

    add_action( 'admin_footer', 'user_profile_fields_disable_js' );

}

function user_profile_fields_disable_js() {
?>
    <script>
        jQuery(document).ready( function($) {
            var fields_to_disable = ['email'];
            for(i=0; i<fields_to_disable.length; i++) {
                if ( $('#'+ fields_to_disable[i]).length ) {
                    $('#'+ fields_to_disable[i]).attr("disabled");
                    $('#'+ fields_to_disable[i]).after("<span class=\"description\"> " + fields_to_disable[i] + " cannot be changed.</span>");
                }
            }
        });
    </script>
<?php
}

Resources

https://www.role-editor.com/hide-disable-wordpress-user-profile-fields/

| improve this answer | |
1

You can use JQuery to disable the email (and any other fields in the edit profile page).

For example, something like this in a plugin:

  //Disables certain fields (email, password) in WP Admin edit user page (user-edit.php)
   global $pagenow;
   if ( $pagenow == 'user-edit.php' ) {
        add_action( 'admin_footer', 'disable_userprofile_fields' );
   }

    /**
    * Disables certain fields (email, password) in WP Admin edit user page (user-edit.php)
    */
    function disable_userprofile_fields() {
    ?>
        <script>
            jQuery(document).ready( function($) {
                if ( $('input[name=email]').length ) {
                    $('input[name=email]').attr("disabled", "disabled");
                }
                if ( $('input[name=pass1]').length ) {
                    $('input[name=pass1]').attr("disabled", "disabled");
                }
                if ( $('input[name=pass2]').length ) {
                    $('input[name=pass2]').attr("disabled", "disabled");
                }
            });
        </script>
    <?php
    }
| improve this answer | |
0

The only correct solution

(Other answers are not the correct because of their side-effects and incompleteness.)

This plugin does correctly:

class DisableMailChange
{

    public function __construct()
    {
        //prevent email change
        add_action( 'personal_options_update',  [$this, 'disable_mail_change_BACKEND'], 5  );
        add_action( 'show_user_profile',        [$this, 'disable_mail_change_HTML']  ); 
    }

    public function disable_mail_change_BACKEND($user_id) {
        if ( !current_user_can( 'manage_options' ) ) { 
            $user = get_user_by('id', $user_id ); $_POST['email']=$user->user_email; 
        } 
    }

    public function disable_mail_change_HTML($user) {
        if ( !current_user_can( 'manage_options' ) ) { 
            echo '<script>document.getElementById("email").setAttribute("disabled","disabled");</script>';
        } 
    }
}
new DisableMailChange();
| improve this answer | |
-1

The hack given below has been tested with WordPress 3.1.

Open user-edit.php, find:

<th><label for="email"><?php _e('E-mail'); ?> <span class="description"><?php _e('(required)'); ?></span></label></th>
<td><input type="text" name="email" id="email" value="<?php echo esc_attr($profileuser->user_email) ?>" class="regular-text" /></span>

and replace with:

<th><label for="email"><?php _e('E-mail'); ?> <span class="description"></span></label></th>
<td><input type="hidden" name="email" id="email" value="<?php echo esc_attr($profileuser->user_email) ?>" class="regular-text" /><?php echo esc_attr($profileuser->user_email) ?></span>

It is just a workaround that visually removes the ability to change email addresses, not actually disable the feature.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy