webtechnick / CakePHP-Facebook-Plugin

CakePHP Facebook Plugin
http://facebook.webtechnick.com
445 stars 138 forks source link

__syncFacebookUser does not account for an existing "site" user #81

Open starchildno1 opened 12 years ago

starchildno1 commented 12 years ago

//attempt to find user by facebook_id- has no commonality with the user table as a whole. So if an already registered user has the same email as a facebook account, then a new account will be created and not an update of the existing account with the facebook_id.

facebook_id is only used to auto login a site user who is already logged into facebook. Therefore, finding a user by email will associate the user table with the facebook account. This goes in the else condition after // check if the user already has an account // User is logged in but doesn't have a facebook id condition

        // attempt to find the user by their email (not facebook id)
        $this->authUser = $this->User->findByEmail($this->me['email']);
        //if we have a user, set hasAccount
        if(!empty($this->authUser)){
            //but they don't have a facebook id then update facebook_id field
            if (empty($this->authUser['User']['facebook_id'])) {
                $this->User->id = $this->authUser['User']['id'];
                $this->User->saveField('facebook_id', $this->uid);
            }
            $this->hasAccount = true;
        }

$this->me has to be set in the initialize function to get the email.

$this->me = $this->FB->api('/me');

It will be reset in the user function by $this->me = $this->Controller->Session->read

Now if an existing user that signed up with your site account activation, decides to login with facebook to share, like and whats not. A totally new user won't be created in the user table and f things up.

aldeed commented 11 years ago

I'd like this added, too.

aldeed commented 11 years ago

In case anyone else cares about this, you can match up new FB accounts with current user accounts in beforeFacebookSave() like so:

function beforeFacebookSave() {
        $emailAddress = $this->Connect->user('email');
        if (empty($emailAddress)) {
            $uid = $this->Connect->user('username');
            if (empty($uid)) {
                $uid = $this->Connect->user('id');
            }
            $emailAddress = "$uid@facebook.com";
        }

        $this->Connect->authUser['User']['username'] = strtolower($emailAddress);

        //match with existing user with this username (e-mail) if there is one
        //specifying the ID will cause this to update that user record instead of creating a new one
        $this->loadModel('User');
        $existingUser = $this->User->findByUsername($this->Connect->authUser['User']['username']);
        if ($existingUser) {
            $this->Connect->authUser['User']['id'] = $existingUser['User']['id'];
            unset($this->Connect->authUser['User']['password']); //clear the password so that the user's current password isn't overwritten
        }
        return true;
}

Note that I save the e-mail as the username in this example, but you could swap all the "username"s with "email" if you have a separate email database column.