How to add Wp_error using lostpassword_post hook when validating custom field?

As of WordPress 4.4, the action lostpassword_post passes the $errors object:

function wpse_185243_lastpassword_post( $errors ) {
    if ( ! $captcha_valid /* The result of your captcha */ ) {
        $errors->add( 'invalid_captcha', '<strong>ERROR:</strong> Try again sonny.' );
    }
}

add_action( 'lostpassword_post', 'wpse_185243_lastpassword_post' );

Pre 4.4 legacy answer

Here’s the relevant code you’re referring to (retrieve_password() in wp-login.php):

function retrieve_password() {
    $errors = new WP_Error();

    // Some error checking

    do_action( 'lostpassword_post' );

    if ( $errors->get_error_code() )
        return $errors;


    // Some more code

    /**
     * Filter whether to allow a password to be reset.
     *
     * @since 2.7.0
     *
     * @param bool true           Whether to allow the password to be reset. Default true.
     * @param int  $user_data->ID The ID of the user attempting to reset a password.
     */
    $allow = apply_filters( 'allow_password_reset', true, $user_data->ID );

    if ( ! $allow )
        return new WP_Error('no_password_reset', __('Password reset is not allowed for this user'));
    else if ( is_wp_error($allow) )
        return $allow;
}

As you say, there’s no way to get hold of $errors (it’s a local variable and is never passed to a filter/action – might be worth filing a feature request in a trac ticket).

However, it appears you can use allow_password_reset to return a new WP_Error, and WordPress will handle it in the same way as a core error:

function wpse_185243_lost_password_captcha( $result, $user_id ) {   
    if ( ! $captcha_valid /* The result of your captcha */ ) {
        $result = new WP_Error( 'invalid_captcha', '<strong>ERROR:</strong> Try again sonny.' );
    }

    return $result;
}

add_filter( 'allow_password_reset', 'wpse_185243_lost_password_captcha', 10, 2 );

Leave a Comment