1

I'm working on a WP 4.9.8 and looking for a script to force users to change their password on their first viewing of the site. It's an enterprise website, users are added by import of a csv file with false email. The email cannot to be changed.

The form to change the password must be in a page, it cannot be the profile.php page.

I found the code of Simon Blackbourn (https://github.com/lumpysimon/wp-force-password-change) but :

  • the form is in a model of page and I wish a shortcode to display it in a page created with Elementor. I don't know how to create this shortcode
  • the form is well displayed at the first connexion but nothing happens after submit it.
  • the redirection after success submit must be an other page depending of the user role (I created 3 user roles : national manager, agency manager, personal). I installed Peter's role redirection (if I remember well the name of the plugin)

I found a plugin on the WP website but it opens the profile.php page (Force change password).

I found the code from pippinsplugins page (https://pippinsplugins.com/change-password-form-short-code/) wich displays the form with the shortcode.

But I don't know how to do with them to do what I need. Thanks a lot and sorry if I'm not very understandable, i'm French ;-)


I think I'll become crazy :-( Nothing works. The login page is a custom page with a shortcode displaying the form. 1. The redirect with Force password change plugin doesn't work. It's ok only if Peter's redirected is actived with the link to the page to change the password. I try different way. If I don't have error anymore, it's not good. User is log in, but not redirected to the change password page, it's always the page with the form to log in. The last test I did is with this in Force Change Password plugin by adding lines after wp_get_current_user():

function force_password_change_redirect() {

    global $current_user;

    if ( is_admin() ) {
        $screen = get_current_screen();
        if ( 'profile' == $screen->base )
            return;
        if ( 'plugins' == $screen->base )
            return;
    }

    if ( !is_user_logged_in() )
        return;

    wp_get_current_user();
if( isset($user->ID) ) {
     $changed_password = get_user_meta( $current_user->ID, 'force-password-change', true ) ;
  if( $changed_password == true ) {
        return get_site_url('/changement-mdp/');
        } else {
         return $redirect_to;
       }
        }
}
  1. I added a line in pippin code to delete the usermeta force-password-change after changing but it doesn't work. No error but I see always this meta_key and its value in the database

    if(empty($errors)) { // change the password here $user_data = array( 'ID' => $user_ID, 'user_pass' => $_POST['pippin_user_pass'] ); wp_update_user($user_data); delete_user_meta( $user_id, 'force-password-change',1 ); // send password change email here (if WP doesn't) wp_redirect(add_query_arg('password-reset', 'true', $_POST['pippin_redirect'])); exit; }

  2. The redirect after succes change password doesn't work. Password is changed but I come back on the page to change the password.

I installed Peter's redirection to redirect users by his role. How to do to redirect him AFTER he have changed his password and not before ?

Thank you for the help I'm completly lost !


Edit december 19th

I'm always looking for a solution. I tried to modify the Force Change Password plugin by adding the code from pippinplugins. But there are certainly a lot of errors because I've a white page on the front-end and on the admin. Could you help me to find the errors ?

Thanks a lot

<?php
/*
Plugin Name:  Force Password Change
Description:  Require users to change their password on first login.
Version:      0.6
License:      GPL v2 or later
Plugin URI:   https://github.com/lumpysimon/wp-force-password-change
Author:       Simon Blackbourn
Author URI:   https://twitter.com/lumpysimon
Author Email: [email protected]
Text Domain:  force-password-change
Domain Path:  /languages/



About this plugin
-----------------

This plugin redirects newly-registered users to the Admin -> Edit Profile page when they first log in.
Until they have changed their password, they will not be able to access either the front-end or other admin pages.
An admin notice is also displayed informing them that they must change their password.

New administrators must also change their password, but as a safety measure they can also access the Admin -> Plugins page.

Please report any bugs on the WordPress support forum at http://wordpress.org/support/plugin/force-password-change or via GitHub at https://github.com/lumpysimon/wp-force-password-change/issues

Development takes place at https://github.com/lumpysimon/wp-force-password-change (all pull requests will be considered)



About me
--------

I'm Simon Blackbourn, co-founder of Lumpy Lemon, a small & friendly UK-based
WordPress design & development company specialising in custom-built WordPress CMS sites.
I work mainly, but not exclusively, with not-for-profit organisations.

Find me on Twitter, Skype & GitHub: lumpysimon



License
-------

Copyright (c) Lumpy Lemon Ltd. All rights reserved.

Released under the GPL license:
http://www.opensource.org/licenses/gpl-license.php

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.



*/



$force_password_change = new force_password_change;



class force_password_change {



// just a bunch of functions called from various hooks
function __construct() {

    add_action( 'init',                    array( $this, 'init' ) );
    add_action( 'user_register',           array( $this, 'registered' ) );
    add_action( 'personal_options_update', array( $this, 'updated' ) );
    add_action( 'template_redirect',       array( $this, 'redirect' ) );
    add_action( 'current_screen',          array( $this, 'redirect' ) );
    add_action( 'admin_notices',           array( $this, 'notice' ) );

}



// load localisation files
function init() {

    load_plugin_textdomain(
        'force-password-change',
        false,
        dirname( plugin_basename( __FILE__ ) ) . '/languages'
        );

}



// on ajoute un champ meta dans la table users_meta avec la valeur 1 lors de l'enregistrement
function registered( $user_id ) {

    add_user_meta( $user_id, 'force-password-change', 1 );

}
    // on efface cette valeur quand le mot de passe a été changé
function updated( $user_id ) {

    if($_POST['pippin_user_pass'] == $_POST['pippin_user_pass_confirm']) {

    delete_user_meta( $user_id, 'force-password-change' );
    }
}

/*shortcode pour modifier le mdp*/
function pippin_change_password_form() {
global $post;

if (is_singular()) :
    $current_url = get_permalink($post->ID);
else :
    $pageURL = 'http';
    if ($_SERVER["HTTPS"] == "on") $pageURL .= "s";
    $pageURL .= "://";
    if ($_SERVER["SERVER_PORT"] != "80") $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
    else $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
    $current_url = $pageURL;
endif;
if(empty($errors)){
$redirect = home_url();}
else {
$redirect = $current_url;}

ob_start();

    // afficher les éventuelles erreurs lors de la saisie du nouveau mot de passe
    pippin_show_error_messages(); ?>

    <?php if(isset($_GET['password-reset']) && $_GET['password-reset'] == 'true') { ?>
        <div class="pippin_message success">
            <span><?php _e('Password changed successfully', 'rcp'); ?></span>
        </div>
    <?php } ?>
    <form id="pippin_password_form" method="POST" action="<?php echo esc_url($url); ?>">
        <fieldset>
            <p>
                <label for="pippin_user_pass"><?php _e('New Password', 'rcp'); ?></label>
                <input name="pippin_user_pass" id="pippin_user_pass" class="required" type="password"/>
            </p>
            <p>
                <label for="pippin_user_pass_confirm"><?php _e('Password Confirm', 'rcp'); ?></label>
                <input name="pippin_user_pass_confirm" id="pippin_user_pass_confirm" class="required" type="password"/>
            </p>
            <p>
                <input type="hidden" name="pippin_action" value="reset-password"/>
                <input type="hidden" name="pippin_redirect" value="<?php echo $redirect; ?>"/>
                <input type="hidden" name="pippin_password_nonce" value="<?php echo wp_create_nonce('rcp-password-nonce'); ?>"/>
                <input id="pippin_password_submit" type="submit" value="<?php _e('Change Password', 'pippin'); ?>"/>
            </p>
        </fieldset>
    </form>
<?php
return ob_get_clean();
}

// le formulaire de modification de mot de passe
function pippin_reset_password_form() {
if(is_user_logged_in()) {
    return pippin_change_password_form();
}
}
add_shortcode('password_form', 'pippin_reset_password_form');


// si:
// - on est loggé,
// - le champ meta est présent pour cet utilisateur,
// - on est sur le front-end ou n'importe quel écran sauf la page d'édition de profil ou plugins,
// alors on redirige vers la page de changement de mot de passe (modif code Force Password Change)
function force_password_change_redirect() {

    global $current_user;

    if ( is_admin() ) {
        $screen = get_current_screen();
        if ( 'profile' == $screen->base )
            return;
        if ( 'plugins' == $screen->base )
            return;
    }

    if ( !is_user_logged_in() )
        return;

    wp_get_current_user();

     $changed_password = get_user_meta( $current_user->ID, 'force-password-change', true ) ;
  if( $changed_password == true ) {
        return get_site_url('/changement-mdp/');
        } else {
         return $redirect_to;
       }

}

function pippin_reset_password() {
// reset a users password
if(isset($_POST['pippin_action']) && $_POST['pippin_action'] == 'reset-password') {

    global $user_ID;

    if(!is_user_logged_in())
        return;

    if(wp_verify_nonce($_POST['pippin_password_nonce'], 'rcp-password-nonce')) {

        if($_POST['pippin_user_pass'] == '' || $_POST['pippin_user_pass_confirm'] == '') {
            // password(s) field empty
            pippin_errors()->add('password_empty', __('Please enter a password, and confirm it', 'pippin'));
        }
        if($_POST['pippin_user_pass'] != $_POST['pippin_user_pass_confirm']) {
            // passwords do not match
            pippin_errors()->add('password_mismatch', __('Passwords do not match', 'pippin'));
        }

        // retrieve all error messages, if any
        $errors = pippin_errors()->get_error_messages();

        if(empty($errors)) {
            // change the password here
            $user_data = array(
                'ID' => $user_ID,
                'user_pass' => $_POST['pippin_user_pass']
            );
    delete_user_meta( $user_id, 'force-password-change',1 );
            wp_update_user($user_data);

            // send password change email here (if WP doesn't)
            wp_redirect(add_query_arg('password-reset', 'true', $_POST['pippin_redirect']));
            exit;
        }
    }
}
}
add_action('init', 'pippin_reset_password');

if(!function_exists('pippin_show_error_messages')) {
// displays error messages from form submissions
function pippin_show_error_messages() {
    if($codes = pippin_errors()->get_error_codes()) {
        echo '<div class="pippin_message error">';
            // Loop error codes and display errors
           foreach($codes as $code){
                $message = pippin_errors()->get_error_message($code);
                echo '<span class="pippin_error"><strong>' . __('Error', 'rcp') . '</strong>: ' . $message . '</span><br/>';
            }
        echo '</div>';
    }
}
}

if(!function_exists('pippin_errors')) {
// used for tracking error messages
function pippin_errors(){
    static $wp_error; // Will hold global variable safely
    return isset($wp_error) ? $wp_error : ($wp_error = new WP_Error(null, null, null));
}
}
// if the user meta field is present, display an admin notice
function notice() {

    global $current_user;

    wp_get_current_user();

    if ( get_user_meta( $current_user->ID, 'force-password-change', true ) ) {
        printf(
            '<div class="error"><p>%s</p></div>',
            __( 'Please change your password in order to continue using this website', 'force-password-change' )
            );
    }

}



} // class

Thanks for your help !

3
  • Take out the white space before the opening <?php
    – anmari
    Dec 20, 2018 at 2:41
  • thanks for your reply. Don't worry, there is no white space in my file. I added it to display in the block code otherwise it was not displayed in Dec 20, 2018 at 8:21
  • Happy New Year to everybody ! I'm sorry but I always need help with this code. The redirect to the page doesn't work. And the field in the database is not ugraded :-(. Thanks a lot ! Dec 26, 2018 at 19:35

1 Answer 1

1

You've got almost everything you need already (assuming the above plugins that you listed work). You just need to link them:

  1. Activate pippins change password plugin & create a page with the shortcode for that in it. Test that that page allows a logged in user to change their password. Note the URL of the page and DO NOT change it.
  2. Now edit the wp-force-password-change plugin (or check if it allows one to specify the url in a setting). Find the part where it specifies the URL to always redirect to. You said it's the profile.php? Change that url to be the one of the page you created. Save, upload, activate, test.

If both plugins and it sounds like they do from what you described, then that should do it.

Always a good idea to test that once a user has been forced to change their password, when they logoff and login again, they are not forced to change it again. ;)

3
  • Hi ! I added the code of pippin in functions.php (there is not a plugin) and added the shortcode into a page. It works ;-) Now I wish to add the link in force-change-password. Actually the redirect is like that : wp_redirect(admin_url('profile.php')); Can I get : wp_admin('link-to-my-page'); ? Dec 16, 2018 at 18:31
  • No - since presumably your page is not an admin page. Looks like you figured that out.
    – anmari
    Dec 17, 2018 at 0:51
  • Yes, it was a mistake, I mean : can I replace by wp_redirect(site_url'/changement-mdp') or is it better to get $redirect_url=site_url('/changement-mdp') ? Dec 18, 2018 at 13:34

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.