/** * Select content based on author RoleID * * @param array $Parameters * @return boolean */ protected function SelectByRole($Parameters) { if (!is_array($Parameters)) { $RoleID = $Parameters; } else { $RoleID = GetValue('RoleID', $Parameters, NULL); } // Lookup role name -> roleID if (is_string($RoleID)) { $RoleModel = new RoleModel(); $Roles = explode(',', $RoleID); $RoleID = array(); foreach ($Roles as $TestRoleID) { $TestRoleID = trim($TestRoleID); $Role = $RoleModel->GetByName($TestRoleID); if (!$Role) { continue; } else { $Role = array_shift($Role); $RoleID[] = GetValue('RoleID', $Role); } } } if (empty($RoleID) || !sizeof($RoleID)) { return FALSE; } // Check cache $SelectorRoleCacheKey = "modules.promotedcontent.role.{$RoleID}"; $Content = Gdn::Cache()->Get($SelectorRoleCacheKey); if ($Content == Gdn_Cache::CACHEOP_FAILURE) { // Get everyone with this Role $UserIDs = Gdn::SQL()->Select('ur.UserID')->From('UserRole ur')->Where('ur.RoleID', $RoleID)->GroupBy('UserID')->Get()->Result(DATASET_TYPE_ARRAY); $UserIDs = ConsolidateArrayValuesByKey($UserIDs, 'UserID'); // Get matching Discussions $Discussions = Gdn::SQL()->Select('d.*')->From('Discussion d')->WhereIn('d.InsertUserID', $UserIDs)->OrderBy('DateInserted', 'DESC')->Limit($this->Limit)->Get()->Result(DATASET_TYPE_ARRAY); // Get matching Comments $Comments = Gdn::SQL()->Select('c.*')->From('Comment c')->WhereIn('InsertUserID', $UserIDs)->OrderBy('DateInserted', 'DESC')->Limit($this->Limit)->Get()->Result(DATASET_TYPE_ARRAY); $this->JoinCategory($Comments); // Interleave $Content = $this->Union('DateInserted', array('Discussion' => $Discussions, 'Comment' => $Comments)); $this->Prepare($Content); // Add result to cache Gdn::Cache()->Store($SelectorRoleCacheKey, $Content, array(Gdn_Cache::FEATURE_EXPIRY => $this->Expiry)); } $this->Security($Content); $this->Condense($Content, $this->Limit); return $Content; }
/** * Connect the user with an external source. * * This controller method is meant to be used with plugins that set its data array to work. * Events: ConnectData * * @since 2.0.0 * @access public * * @param string $Method Used to register multiple providers on ConnectData event. */ public function Connect($Method) { $this->AddJsFile('entry.js'); $this->View = 'connect'; $IsPostBack = $this->Form->IsPostBack() && $this->Form->GetFormValue('Connect', NULL) !== NULL; if (!$IsPostBack) { // Here are the initial data array values. that can be set by a plugin. $Data = array('Provider' => '', 'ProviderName' => '', 'UniqueID' => '', 'FullName' => '', 'Name' => '', 'Email' => '', 'Photo' => '', 'Target' => $this->Target()); $this->Form->SetData($Data); $this->Form->AddHidden('Target', $this->Request->Get('Target', '/')); } // The different providers can check to see if they are being used and modify the data array accordingly. $this->EventArguments = array($Method); // Fire ConnectData event & error handling. $CurrentData = $this->Form->FormValues(); try { $this->FireEvent('ConnectData'); } catch (Gdn_UserException $Ex) { $this->Form->AddError($Ex); return $this->Render('ConnectError'); } catch (Exception $Ex) { if (Debug()) { $this->Form->AddError($Ex); } else { $this->Form->AddError('There was an error fetching the connection data.'); } return $this->Render('ConnectError'); } if (!UserModel::NoEmail()) { if (!$this->Form->GetFormValue('Email') || $this->Form->GetFormValue('EmailVisible')) { $this->Form->SetFormValue('EmailVisible', TRUE); $this->Form->AddHidden('EmailVisible', TRUE); if ($IsPostBack) { $this->Form->SetFormValue('Email', GetValue('Email', $CurrentData)); } } } $FormData = $this->Form->FormValues(); // debug // Make sure the minimum required data has been provided to the connect. if (!$this->Form->GetFormValue('Provider')) { $this->Form->AddError('ValidateRequired', T('Provider')); } if (!$this->Form->GetFormValue('UniqueID')) { $this->Form->AddError('ValidateRequired', T('UniqueID')); } if (!$this->Data('Verified')) { // Whatever event handler catches this must Set the data 'Verified' to true to prevent a random site from connecting without credentials. // This must be done EVERY postback and is VERY important. $this->Form->AddError('The connection data has not been verified.'); } if ($this->Form->ErrorCount() > 0) { return $this->Render(); } $UserModel = Gdn::UserModel(); // Check to see if there is an existing user associated with the information above. $Auth = $UserModel->GetAuthentication($this->Form->GetFormValue('UniqueID'), $this->Form->GetFormValue('Provider')); $UserID = GetValue('UserID', $Auth); // Check to synchronise roles upon connecting. if (($this->Data('Trusted') || C('Garden.SSO.SynchRoles')) && $this->Form->GetFormValue('Roles', NULL) !== NULL) { $SaveRoles = TRUE; // Translate the role names to IDs. $Roles = $this->Form->GetFormValue('Roles', NULL); $Roles = RoleModel::GetByName($Roles); $RoleIDs = array_keys($Roles); if (empty($RoleIDs)) { // The user must have at least one role. This protects that. $RoleIDs = $this->UserModel->NewUserRoleIDs(); } $this->Form->SetFormValue('RoleID', $RoleIDs); } else { $SaveRoles = FALSE; } if ($UserID) { // The user is already connected. $this->Form->SetFormValue('UserID', $UserID); if (C('Garden.Registration.ConnectSynchronize', TRUE)) { $User = Gdn::UserModel()->GetID($UserID, DATASET_TYPE_ARRAY); $Data = $this->Form->FormValues(); // Don't overwrite the user photo if the user uploaded a new one. $Photo = GetValue('Photo', $User); if (!GetValue('Photo', $Data) || $Photo && !StringBeginsWith($Photo, 'http')) { unset($Data['Photo']); } // Synchronize the user's data. $UserModel->Save($Data, array('NoConfirmEmail' => TRUE, 'FixUnique' => TRUE, 'SaveRoles' => $SaveRoles)); } // Always save the attributes because they may contain authorization information. if ($Attributes = $this->Form->GetFormValue('Attributes')) { $UserModel->SaveAttribute($UserID, $Attributes); } // Sign the user in. Gdn::Session()->Start($UserID, TRUE, TRUE); Gdn::UserModel()->FireEvent('AfterSignIn'); // $this->_SetRedirect(TRUE); $this->_SetRedirect($this->Request->Get('display') == 'popup'); } elseif ($this->Form->GetFormValue('Name') || $this->Form->GetFormValue('Email')) { $NameUnique = C('Garden.Registration.NameUnique', TRUE); $EmailUnique = C('Garden.Registration.EmailUnique', TRUE); $AutoConnect = C('Garden.Registration.AutoConnect'); // Get the existing users that match the name or email of the connection. $Search = FALSE; if ($this->Form->GetFormValue('Name') && $NameUnique) { $UserModel->SQL->OrWhere('Name', $this->Form->GetFormValue('Name')); $Search = TRUE; } if ($this->Form->GetFormValue('Email') && ($EmailUnique || $AutoConnect)) { $UserModel->SQL->OrWhere('Email', $this->Form->GetFormValue('Email')); $Search = TRUE; } if ($Search) { $ExistingUsers = $UserModel->GetWhere()->ResultArray(); } else { $ExistingUsers = array(); } // Check to automatically link the user. if ($AutoConnect && count($ExistingUsers) > 0) { foreach ($ExistingUsers as $Row) { if ($this->Form->GetFormValue('Email') == $Row['Email']) { $UserID = $Row['UserID']; $this->Form->SetFormValue('UserID', $UserID); $Data = $this->Form->FormValues(); if (C('Garden.Registration.ConnectSynchronize', TRUE)) { // Don't overwrite a photo if the user has already uploaded one. $Photo = GetValue('Photo', $Row); if (!GetValue('Photo', $Data) || $Photo && !StringBeginsWith($Photo, 'http')) { unset($Data['Photo']); } $UserModel->Save($Data, array('NoConfirmEmail' => TRUE, 'FixUnique' => TRUE, 'SaveRoles' => $SaveRoles)); } if ($Attributes = $this->Form->GetFormValue('Attributes')) { $UserModel->SaveAttribute($UserID, $Attributes); } // Save the userauthentication link. $UserModel->SaveAuthentication(array('UserID' => $UserID, 'Provider' => $this->Form->GetFormValue('Provider'), 'UniqueID' => $this->Form->GetFormValue('UniqueID'))); // Sign the user in. Gdn::Session()->Start($UserID, TRUE, TRUE); Gdn::UserModel()->FireEvent('AfterSignIn'); // $this->_SetRedirect(TRUE); $this->_SetRedirect($this->Request->Get('display') == 'popup'); $this->Render(); return; } } } $CurrentUserID = Gdn::Session()->UserID; // Massage the existing users. foreach ($ExistingUsers as $Index => $UserRow) { if ($EmailUnique && $UserRow['Email'] == $this->Form->GetFormValue('Email')) { $EmailFound = $UserRow; break; } if ($UserRow['Name'] == $this->Form->GetFormValue('Name')) { $NameFound = $UserRow; } if ($CurrentUserID > 0 && $UserRow['UserID'] == $CurrentUserID) { unset($ExistingUsers[$Index]); $CurrentUserFound = TRUE; } } if (isset($EmailFound)) { // The email address was found and can be the only user option. $ExistingUsers = array($UserRow); $this->SetData('NoConnectName', TRUE); } elseif (isset($CurrentUserFound)) { $ExistingUsers = array_merge(array('UserID' => 'current', 'Name' => sprintf(T('%s (Current)'), Gdn::Session()->User->Name)), $ExistingUsers); } if (!isset($NameFound) && !$IsPostBack) { $this->Form->SetFormValue('ConnectName', $this->Form->GetFormValue('Name')); } $this->SetData('ExistingUsers', $ExistingUsers); if (UserModel::NoEmail()) { $EmailValid = TRUE; } else { $EmailValid = ValidateRequired($this->Form->GetFormValue('Email')); } if ($this->Form->GetFormValue('Name') && $EmailValid && (!is_array($ExistingUsers) || count($ExistingUsers) == 0)) { // There is no existing user with the suggested name so we can just create the user. $User = $this->Form->FormValues(); $User['Password'] = RandomString(50); // some password is required $User['HashMethod'] = 'Random'; $User['Source'] = $this->Form->GetFormValue('Provider'); $User['SourceID'] = $this->Form->GetFormValue('UniqueID'); $User['Attributes'] = $this->Form->GetFormValue('Attributes', NULL); $User['Email'] = $this->Form->GetFormValue('ConnectEmail', $this->Form->GetFormValue('Email', NULL)); // $UserID = $UserModel->InsertForBasic($User, FALSE, array('ValidateEmail' => FALSE, 'NoConfirmEmail' => TRUE, 'SaveRoles' => $SaveRoles)); $UserID = $UserModel->Register($User, array('CheckCaptcha' => FALSE, 'ValidateEmail' => FALSE, 'NoConfirmEmail' => TRUE, 'SaveRoles' => $SaveRoles)); $User['UserID'] = $UserID; $this->Form->SetValidationResults($UserModel->ValidationResults()); if ($UserID) { $UserModel->SaveAuthentication(array('UserID' => $UserID, 'Provider' => $this->Form->GetFormValue('Provider'), 'UniqueID' => $this->Form->GetFormValue('UniqueID'))); $this->Form->SetFormValue('UserID', $UserID); Gdn::Session()->Start($UserID, TRUE, TRUE); Gdn::UserModel()->FireEvent('AfterSignIn'); // Send the welcome email. if (C('Garden.Registration.SendConnectEmail', FALSE)) { try { $UserModel->SendWelcomeEmail($UserID, '', 'Connect', array('ProviderName' => $this->Form->GetFormValue('ProviderName', $this->Form->GetFormValue('Provider', 'Unknown')))); } catch (Exception $Ex) { // Do nothing if emailing doesn't work. } } $this->_SetRedirect(TRUE); } } } // Save the user's choice. if ($IsPostBack) { // The user has made their decision. $PasswordHash = new Gdn_PasswordHash(); $UserSelect = $this->Form->GetFormValue('UserSelect'); if (!$UserSelect || $UserSelect == 'other') { // The user entered a username. $ConnectNameEntered = TRUE; if ($this->Form->ValidateRule('ConnectName', 'ValidateRequired')) { $ConnectName = $this->Form->GetFormValue('ConnectName'); $User = FALSE; if (C('Garden.Registration.NameUnique')) { // Check to see if there is already a user with the given name. $User = $UserModel->GetWhere(array('Name' => $ConnectName))->FirstRow(DATASET_TYPE_ARRAY); } if (!$User) { $this->Form->ValidateRule('ConnectName', 'ValidateUsername'); } } } else { // The user selected an existing user. $ConnectNameEntered = FALSE; if ($UserSelect == 'current') { if (Gdn::Session()->UserID == 0) { // This shouldn't happen, but a use could sign out in another browser and click submit on this form. $this->Form->AddError('@You were uexpectidly signed out.'); } else { $UserSelect = Gdn::Session()->UserID; } } $User = $UserModel->GetID($UserSelect, DATASET_TYPE_ARRAY); } if (isset($User) && $User) { // Make sure the user authenticates. if (!$User['UserID'] == Gdn::Session()->UserID) { if ($this->Form->ValidateRule('ConnectPassword', 'ValidateRequired', sprintf(T('ValidateRequired'), T('Password')))) { try { if (!$PasswordHash->CheckPassword($this->Form->GetFormValue('ConnectPassword'), $User['Password'], $User['HashMethod'], $this->Form->GetFormValue('ConnectName'))) { if ($ConnectNameEntered) { $this->Form->AddError('The username you entered has already been taken.'); } else { $this->Form->AddError('The password you entered is incorrect.'); } } } catch (Gdn_UserException $Ex) { $this->Form->AddError($Ex); } } } } elseif ($this->Form->ErrorCount() == 0) { // The user doesn't exist so we need to add another user. $User = $this->Form->FormValues(); $User['Name'] = $User['ConnectName']; $User['Password'] = RandomString(50); // some password is required $User['HashMethod'] = 'Random'; $UserID = $UserModel->Register($User, array('CheckCaptcha' => FALSE, 'NoConfirmEmail' => TRUE, 'SaveRoles' => $SaveRoles)); $User['UserID'] = $UserID; $this->Form->SetValidationResults($UserModel->ValidationResults()); if ($UserID) { // // Add the user to the default roles. // $UserModel->SaveRoles($UserID, C('Garden.Registration.DefaultRoles')); // Send the welcome email. $UserModel->SendWelcomeEmail($UserID, '', 'Connect', array('ProviderName' => $this->Form->GetFormValue('ProviderName', $this->Form->GetFormValue('Provider', 'Unknown')))); } } if ($this->Form->ErrorCount() == 0) { // Save the authentication. if (isset($User) && GetValue('UserID', $User)) { $UserModel->SaveAuthentication(array('UserID' => $User['UserID'], 'Provider' => $this->Form->GetFormValue('Provider'), 'UniqueID' => $this->Form->GetFormValue('UniqueID'))); $this->Form->SetFormValue('UserID', $User['UserID']); } // Sign the appropriate user in. Gdn::Session()->Start($this->Form->GetFormValue('UserID', TRUE, TRUE)); Gdn::UserModel()->FireEvent('AfterSignIn'); $this->_SetRedirect(TRUE); } } $this->Render(); }
/** * Select content based on author RoleID. * * @param array|int $Parameters * @return array|false */ protected function selectByRole($Parameters) { if (!is_array($Parameters)) { $RoleID = $Parameters; } else { $RoleID = val('RoleID', $Parameters, null); } // Lookup role name -> roleID if ($RoleID && is_string($RoleID)) { $RoleModel = new RoleModel(); $Roles = explode(',', $RoleID); $RoleID = array(); foreach ($Roles as $TestRoleID) { $TestRoleID = trim($TestRoleID); $Role = $RoleModel->GetByName($TestRoleID); if (!$Role) { continue; } else { $Role = array_shift($Role); $RoleID[] = val('RoleID', $Role); } } } if (empty($RoleID) || !sizeof($RoleID)) { return false; } // Check cache sort($RoleID); $RoleIDKey = implode('-', $RoleID); $SelectorRoleCacheKey = "modules.promotedcontent.role.{$RoleIDKey}"; $Content = Gdn::cache()->get($SelectorRoleCacheKey); if ($Content == Gdn_Cache::CACHEOP_FAILURE) { // Get everyone with this Role $UserIDs = Gdn::sql()->select('ur.UserID')->from('UserRole ur')->where('ur.RoleID', $RoleID)->groupBy('UserID')->get()->result(DATASET_TYPE_ARRAY); $UserIDs = array_column($UserIDs, 'UserID'); // Get matching Discussions $Discussions = array(); if ($this->ShowDiscussions()) { $Discussions = Gdn::sql()->select('d.*')->from('Discussion d')->whereIn('d.InsertUserID', $UserIDs)->orderBy('DateInserted', 'DESC')->limit($this->Limit)->get()->result(DATASET_TYPE_ARRAY); } // Get matching Comments $Comments = array(); if ($this->ShowComments()) { $Comments = Gdn::sql()->select('c.*')->from('Comment c')->whereIn('InsertUserID', $UserIDs)->orderBy('DateInserted', 'DESC')->limit($this->Limit)->get()->result(DATASET_TYPE_ARRAY); $this->JoinCategory($Comments); } // Interleave $Content = $this->Union('DateInserted', array('Discussion' => $Discussions, 'Comment' => $Comments)); $this->processContent($Content); // Add result to cache Gdn::cache()->store($SelectorRoleCacheKey, $Content, array(Gdn_Cache::FEATURE_EXPIRY => $this->Expiry)); } $this->Security($Content); $this->Condense($Content, $this->Limit); return $Content; }