Modifying a function to return username correctly, for a wordpress plugin

I have two WordPress Plugins and both authors of the plugins refuse to admit the clash/issue is their site but it’s quite clear that both parties can fix the issue very easily.

I provided one plugin author with the fix that has no negative impact on their plugin in any way, it doesn’t cause any problems if the person has the second plugin installed or not but they won’t add the fix to their plugin even though it adds compatibility with a different plugin.

Read More

I am unable to work out how to fix the second plugin, but I know what needs to be done…

Snippet from Plugin 1 (One that I provided a fix to)

/* check if the user is valid */
if ( true === wlm_admin_in_admin() || true === $special_bypass ) {
    $validuser = username_exists( $data['username'] );

    if ( ! $validuser ) {
        $validuser        = email_exists( $data['email'] );
        $user_info        = get_userdata( $validuser );
        $data['username'] = $user_info->user_login;
    }

    $data['password'] = __( 'Already assigned', 'wishlist-member' );
} else {
    $validuser = wp_login( $data['username'], $data['password'] );
}
if ( $validuser ) {
    $user      = $this->Get_UserData( 0, $data['username'] );
    /* check for blacklist status */
    $blacklist = $this->CheckBlackList( $user->user_email );
}

Now, if find the line:

$validuser = wp_login( $data['username'], $data['password'] );

And replace it with:

//$validuser = wp_login( $data['username'], $data['password'] );
$tmpvaliduser = username_exists( $data['username'] );
if ($tmpvaliduser)
    $validuser = wp_login( $data['username'], $data['password'] );

if ( ! $validuser || !$tmpvaliduser) {     
    if((!$data['email'])  && !(false === strrpos($data['username'], "@")) ) {
        $validuser        = email_exists( $data['username'] );
        $user_info        = get_userdata( $validuser );
        $data['username'] = $user_info->user_login;
        $validuser = wp_login( $data['username'], $data['password'] );  
    }     
}

Then this fixes the issue because it changes the $data['username'] variable to their actual username which means the rest of the plugin 1 will continue correctly and bind certain details to the username (account) rather than a username consisting of their email (which obviously doesn’t exist as a username)

  • If username exists (they tried to login with username & password) then it continues like normal.
  • If username does NOT exist then it checks if the email exists instead, if it does then it will grab the username from the email address that was entered and simply changes the entered username field with their actual username instead of their email and then continues like normal

Snippet from Plugin 2 (One that I need a fix for)

function email_login_authenticate( $user, $username, $password ) {
    if ( is_a( $user, 'WP_User' ) )
        return $user;
    if ( !empty( $username ) ) {
        $user = get_user_by( 'email', $username );
        if ( isset( $user, $user->user_login, $user->user_status ) && 0 == (int) $user->user_status ) {
            $username = $user->user_login;
        }
        $result = wp_authenticate_username_password( null, $username, $password );
        if (is_a ( $result, 'WP_User' ) ) {
            global $WishListMemberInstance;
            $WishListMemberInstance->WPMAutoLogin($user->ID);
            $_POST['log'] = $username;
            $WishListMemberInstance->Login();
        }
    }
    return wp_authenticate_username_password( null, $username, $password );
}

I’m not 100% sure what the above snippit does in full, but I understand it good enough and I need to change it so that it returns the correct username somehow so that $data['username'] is replaced with the username instead of the email (if an email is used)

Related posts

1 comment

  1. First, my wordpress version

    Name        : wordpress                    Relocations: (not relocatable)
    Version     : 4.4                               Vendor: Fedora Project
    Release     : 1.el6                         Build Date: Wed 09 Dec 2015 11:40:49 AM EST
    

    plugins on my centos6.4 would be installed at this location:

    /usr/share/wordpress/wp-content/plugins
    

    Please pay attention that this function(on my system) not always return a user, WP_Error as well

    /**
     * Authenticate the user using the username and password.
     *
     * @since 2.8.0
     *
     * @param WP_User|WP_Error|null $user     WP_User or WP_Error object from a previous callback. Default null.
     * @param string                $username Username for authentication.
     * @param string                $password Password for authentication.
     * @return WP_User|WP_Error WP_User on success, WP_Error on failure.
     */
    function wp_authenticate_username_password($user, $username, $password) {
    

    The wp-email-login I found might fit for you:

    http://plugins.svn.wordpress.org/wp-email-login/trunk/email-login.php

    To be more clear, The snippet from plugin 2, should be changed to:

    function email_login_authenticate( $user, $username, $password ) {
        if ( is_a( $user, 'WP_User' ) )
            return $user;
        if ( !empty( $username ) ) {
    
    
            // add this line to format email - propose change #1
                $username = str_replace( '&', '&', stripslashes( $username ) );
            $user = get_user_by( 'email', $username );
            if ( isset( $user, $user->user_login, $user->user_status ) && 0 == (int) $user->user_status ) {
                $username = $user->user_login;
            }
            $result = wp_authenticate_username_password( null, $username, $password );
            if (is_a ( $result, 'WP_User' ) ) {
                // These 4 lines came from plugin2 from your system, keep as is
                global $WishListMemberInstance;
                $WishListMemberInstance->WPMAutoLogin($user->ID);
                $_POST['log'] = $username;
                $WishListMemberInstance->Login();
            }
    
    
            // no need to authenticate another time, return - proposed change #2
            // authenticate twice could be a problem as well
            return $result;
        }
        return wp_authenticate_username_password( null, $username, $password );
    }
    

Comments are closed.