UserModel::synchronize PHP Method

synchronize() public method

Synchronizes the user based on a given UserKey.
public synchronize ( string $UserKey, array $Data ) : integer
$UserKey string A string that uniquely identifies this user.
$Data array Information to put in the user table.
return integer The ID of the user.
    public function synchronize($UserKey, $Data)
    {
        $UserID = 0;
        $Attributes = val('Attributes', $Data);
        if (is_string($Attributes)) {
            $Attributes = dbdecode($Attributes);
        }
        if (!is_array($Attributes)) {
            $Attributes = [];
        }
        // If the user didnt log in, they won't have a UserID yet. That means they want a new
        // account. So create one for them.
        if (!isset($Data['UserID']) || $Data['UserID'] <= 0) {
            // Prepare the user data.
            $UserData = [];
            $UserData['Name'] = $Data['Name'];
            $UserData['Password'] = randomString(16);
            $UserData['Email'] = val('Email', $Data, '[email protected]');
            $UserData['Gender'] = strtolower(substr(val('Gender', $Data, 'u'), 0, 1));
            $UserData['HourOffset'] = val('HourOffset', $Data, 0);
            $UserData['DateOfBirth'] = val('DateOfBirth', $Data, '');
            $UserData['CountNotifications'] = 0;
            $UserData['Attributes'] = $Attributes;
            $UserData['InsertIPAddress'] = ipEncode(Gdn::request()->ipAddress());
            if ($UserData['DateOfBirth'] == '') {
                $UserData['DateOfBirth'] = '1975-09-16';
            }
            // Make sure there isn't another user with this username.
            if ($this->validateUniqueFields($UserData['Name'], $UserData['Email'])) {
                if (!BanModel::checkUser($UserData, $this->Validation, true)) {
                    throw permissionException('Banned');
                }
                // Insert the new user.
                $this->addInsertFields($UserData);
                $UserID = $this->insertInternal($UserData);
            }
            if ($UserID > 0) {
                $NewUserRoleIDs = $this->newUserRoleIDs();
                // Save the roles.
                $Roles = val('Roles', $Data, false);
                if (empty($Roles)) {
                    $Roles = $NewUserRoleIDs;
                }
                $this->saveRoles($UserID, $Roles, false);
            }
        } else {
            $UserID = $Data['UserID'];
        }
        // Synchronize the transientkey from the external user data source if it is present (eg. WordPress' wpnonce).
        if (array_key_exists('TransientKey', $Attributes) && $Attributes['TransientKey'] != '' && $UserID > 0) {
            $this->setTransientKey($UserID, $Attributes['TransientKey']);
        }
        return $UserID;
    }

Usage Example

 /**
  * Attempt to syncronize user data from remote system into Dashboard.
  *
  * @access public
  * @since 2.0.?
  * @author Tim Gunter
  *
  * @param object $Authenticator
  * @param array $UserInfo
  * @param array $Payload
  */
 public function syncScreen($Authenticator, $UserInfo, $Payload)
 {
     $this->addJsFile('entry.js');
     $this->View = 'handshake';
     $this->HandshakeScheme = $Authenticator->getAuthenticationSchemeAlias();
     $this->Form->setModel($this->UserModel);
     $this->Form->addHidden('ClientHour', date('Y-m-d H:00'));
     // Use the server's current hour as a default
     $this->Form->addHidden('Target', $this->target());
     $PreservedKeys = array('UserKey', 'Token', 'Consumer', 'Email', 'Name', 'Gender', 'HourOffset');
     $UserID = 0;
     $Target = $this->target();
     if ($this->Form->isPostBack() === true) {
         $FormValues = $this->Form->formValues();
         if (val('StopLinking', $FormValues)) {
             $AuthResponse = Gdn_Authenticator::AUTH_ABORTED;
             $UserEventData = array_merge(array('UserID' => $UserID, 'Payload' => $Payload), $UserInfo);
             Gdn::authenticator()->trigger($AuthResponse, $UserEventData);
             $Authenticator->deleteCookie();
             Gdn::request()->withRoute('DefaultController');
             return Gdn::dispatcher()->dispatch();
         } elseif (val('NewAccount', $FormValues)) {
             $AuthResponse = Gdn_Authenticator::AUTH_CREATED;
             // Try and synchronize the user with the new username/email.
             $FormValues['Name'] = $FormValues['NewName'];
             $FormValues['Email'] = $FormValues['NewEmail'];
             $UserID = $this->UserModel->synchronize($UserInfo['UserKey'], $FormValues);
             $this->Form->setValidationResults($this->UserModel->validationResults());
         } else {
             $AuthResponse = Gdn_Authenticator::AUTH_SUCCESS;
             // Try and sign the user in.
             $PasswordAuthenticator = Gdn::authenticator()->authenticateWith('password');
             $PasswordAuthenticator->hookDataField('Email', 'SignInEmail');
             $PasswordAuthenticator->hookDataField('Password', 'SignInPassword');
             $PasswordAuthenticator->fetchData($this->Form);
             $UserID = $PasswordAuthenticator->authenticate();
             if ($UserID < 0) {
                 $this->Form->addError('ErrorPermission');
             } elseif ($UserID == 0) {
                 $this->Form->addError('ErrorCredentials');
                 Logger::event('signin_failure', Logger::WARNING, '{username} failed to sign in. Invalid credentials.');
             }
             if ($UserID > 0) {
                 $Data = $FormValues;
                 $Data['UserID'] = $UserID;
                 $Data['Email'] = val('SignInEmail', $FormValues, '');
                 $UserID = $this->UserModel->synchronize($UserInfo['UserKey'], $Data);
             }
         }
         if ($UserID > 0) {
             // The user has been created successfully, so sign in now
             // Finalize the link between the forum user and the foreign userkey
             $Authenticator->finalize($UserInfo['UserKey'], $UserID, $UserInfo['ConsumerKey'], $UserInfo['TokenKey'], $Payload);
             $UserEventData = array_merge(array('UserID' => $UserID, 'Payload' => $Payload), $UserInfo);
             Gdn::authenticator()->trigger($AuthResponse, $UserEventData);
             /// ... and redirect them appropriately
             $Route = $this->redirectTo();
             if ($Route !== false) {
                 redirect($Route);
             }
         } else {
             // Add the hidden inputs back into the form.
             foreach ($FormValues as $Key => $Value) {
                 if (in_array($Key, $PreservedKeys)) {
                     $this->Form->addHidden($Key, $Value);
                 }
             }
         }
     } else {
         $Id = Gdn::authenticator()->getIdentity(true);
         if ($Id > 0) {
             // The user is signed in so we can just go back to the homepage.
             redirect($Target);
         }
         $Name = $UserInfo['UserName'];
         $Email = $UserInfo['UserEmail'];
         // Set the defaults for a new user.
         $this->Form->setFormValue('NewName', $Name);
         $this->Form->setFormValue('NewEmail', $Email);
         // Set the default for the login.
         $this->Form->setFormValue('SignInEmail', $Email);
         $this->Form->setFormValue('Handshake', 'NEW');
         // Add the handshake data as hidden fields.
         $this->Form->addHidden('Name', $Name);
         $this->Form->addHidden('Email', $Email);
         $this->Form->addHidden('UserKey', $UserInfo['UserKey']);
         $this->Form->addHidden('Token', $UserInfo['TokenKey']);
         $this->Form->addHidden('Consumer', $UserInfo['ConsumerKey']);
     }
     $this->setData('Name', val('Name', $this->Form->HiddenInputs));
     $this->setData('Email', val('Email', $this->Form->HiddenInputs));
     $this->render();
 }
UserModel