public static function &AllBans() { if (!self::$_AllBans) { self::$_AllBans = Gdn::SQL()->Get('Ban')->ResultArray(); self::$_AllBans = Gdn_DataSet::Index(self::$_AllBans, array('BanID')); } // $AllBans =& self::$_AllBans; return self::$_AllBans; }
public function GetProviders() { $this->SQL->Select('uap.*')->From('UserAuthenticationProvider uap'); if (Gdn::Session()->IsValid()) { $UserID = Gdn::Session()->UserID; $this->SQL->Select('ua.ForeignUserKey', '', 'UniqueID')->Join('UserAuthentication ua', "uap.AuthenticationKey = ua.ProviderKey and ua.UserID = {$UserID}", 'left'); } $Data = $this->SQL->Get()->ResultArray(); $Data = Gdn_DataSet::Index($Data, array('AuthenticationKey')); foreach ($Data as &$Row) { self::_Calculate($Row); } return $Data; }
/** * @param type $Activities * @since 2.1 */ public function JoinComments(&$Activities) { // Grab all of the activity IDs. $ActivityIDs = array(); foreach ($Activities as $Activity) { if ($ID = GetValue('CommentActivityID', $Activity['Data'])) { // This activity shares its comments with another activity. $ActivityIDs[] = $ID; } else { $ActivityIDs[] = $Activity['ActivityID']; } } $ActivityIDs = array_unique($ActivityIDs); $Comments = $this->GetComments($ActivityIDs); $Comments = Gdn_DataSet::Index($Comments, array('ActivityID'), array('Unique' => FALSE)); foreach ($Activities as &$Activity) { $ID = GetValue('CommentActivityID', $Activity['Data']); if (!$ID) { $ID = $Activity['ActivityID']; } if (isset($Comments[$ID])) { $Activity['Comments'] = $Comments[$ID]; } else { $Activity['Comments'] = array(); } } }
public function GetIDs($IDs, $SkipCacheQuery = FALSE) { $DatabaseIDs = $IDs; $Data = array(); if (!$SkipCacheQuery) { $Keys = array(); // Make keys for cache query foreach ($IDs as $UserID) { if (!$UserID) { continue; } $Keys[] = FormatString(self::USERID_KEY, array('UserID' => $UserID)); } // Query cache layer $CacheData = Gdn::Cache()->Get($Keys); if (!is_array($CacheData)) { $CacheData = array(); } foreach ($CacheData as $RealKey => $User) { $ResultUserID = GetValue('UserID', $User); $Data[$ResultUserID] = $User; } //echo "from cache:\n"; //print_r($Data); $DatabaseIDs = array_diff($DatabaseIDs, array_keys($Data)); unset($CacheData); } // Clean out bogus blank entries $DatabaseIDs = array_diff($DatabaseIDs, array(NULL, '')); // If we are missing any users from cache query, fill em up here if (sizeof($DatabaseIDs)) { $DatabaseData = $this->SQL->WhereIn('UserID', $DatabaseIDs)->GetWhere('User')->Result(DATASET_TYPE_ARRAY); $DatabaseData = Gdn_DataSet::Index($DatabaseData, 'UserID'); //echo "from DB:\n"; //print_r($DatabaseData); foreach ($DatabaseData as $DatabaseUserID => $DatabaseUser) { $Data[$DatabaseUserID] = $DatabaseUser; $this->SetCalculatedFields($DatabaseUser); $Result = $this->UserCache($DatabaseUser); } } $this->EventArguments['RequestedIDs'] = $IDs; $this->EventArguments['LoadedUsers'] =& $Data; $this->FireEvent('AfterGetIDs'); return $Data; }
/** * Form to ask for the destination of the move, confirmation and permission check. */ public function ConfirmDiscussionMoves($DiscussionID = NULL) { $Session = Gdn::Session(); $this->Form = new Gdn_Form(); $DiscussionModel = new DiscussionModel(); $this->Title(T('Confirm')); if ($DiscussionID) { $CheckedDiscussions = (array) $DiscussionID; $ClearSelection = FALSE; } else { $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array()); if (!is_array($CheckedDiscussions)) { $CheckedDiscussions = array(); } $ClearSelection = TRUE; } $DiscussionIDs = $CheckedDiscussions; $CountCheckedDiscussions = count($DiscussionIDs); $this->SetData('CountCheckedDiscussions', $CountCheckedDiscussions); // Check for edit permissions on each discussion $AllowedDiscussions = array(); $DiscussionData = $DiscussionModel->SQL->Select('DiscussionID, Name, DateLastComment, CategoryID')->From('Discussion')->WhereIn('DiscussionID', $DiscussionIDs)->Get(); $DiscussionData = Gdn_DataSet::Index($DiscussionData->ResultArray(), array('DiscussionID')); foreach ($DiscussionData as $DiscussionID => $Discussion) { $Category = CategoryModel::Categories($Discussion['CategoryID']); if ($Category && $Category['PermsDiscussionsEdit']) { $AllowedDiscussions[] = $DiscussionID; } } $this->SetData('CountAllowed', count($AllowedDiscussions)); $CountNotAllowed = $CountCheckedDiscussions - count($AllowedDiscussions); $this->SetData('CountNotAllowed', $CountNotAllowed); if ($this->Form->AuthenticatedPostBack()) { // Retrieve the category id $CategoryID = $this->Form->GetFormValue('CategoryID'); $Category = CategoryModel::Categories($CategoryID); $RedirectLink = $this->Form->GetFormValue('RedirectLink'); // User must have add permission on the target category if (!$Category['PermsDiscussionsAdd']) { throw ForbiddenException('@' . T('You do not have permission to add discussions to this category.')); } // Iterate and move. foreach ($AllowedDiscussions as $DiscussionID) { // Create the shadow redirect. if ($RedirectLink) { $Discussion = GetValue($DiscussionID, $DiscussionData); $DiscussionModel->DefineSchema(); $MaxNameLength = GetValue('Length', $DiscussionModel->Schema->GetField('Name')); $RedirectDiscussion = array('Name' => SliceString(sprintf(T('Moved: %s'), $Discussion['Name']), $MaxNameLength), 'DateInserted' => $Discussion['DateLastComment'], 'Type' => 'redirect', 'CategoryID' => $Discussion['CategoryID'], 'Body' => FormatString(T('This discussion has been <a href="{url,html}">moved</a>.'), array('url' => DiscussionUrl($Discussion))), 'Format' => 'Html', 'Closed' => TRUE); $RedirectID = $DiscussionModel->Save($RedirectDiscussion); if (!$RedirectID) { $this->Form->SetValidationResults($DiscussionModel->ValidationResults()); break; } } $DiscussionModel->SetField($DiscussionID, 'CategoryID', $CategoryID); } // Clear selections. if ($ClearSelection) { Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedDiscussions', FALSE); ModerationController::InformCheckedDiscussions($this); } if ($this->Form->ErrorCount() == 0) { $this->JsonTarget('', '', 'Refresh'); } } $this->Render(); }
/** * Joins attachments to data * * <code> * <?php * $AttachmentModel->JoinAttachments($Discussion, $Comments); * ?> * </code> * * @param $Data - Data to which to attach comments * @param $Data2 - Optional set of Data to which to attach comments * */ public function JoinAttachments(&$Data, &$Data2 = NULL) { if ($Data == NULL) { return; } // Gather the Ids. $ForeignIDs = array(); self::GatherIDs($Data, $ForeignIDs); if ($Data2) { self::GatherIDs($Data2, $ForeignIDs); } // Get the attachments. $Attachments = $this->GetWhere(array('ForeignID' => array_keys($ForeignIDs)), 'DateInserted', 'desc')->ResultArray(); $Attachments = Gdn_DataSet::Index($Attachments, 'ForeignID', array('Unique' => FALSE)); // Join the attachments. $this->JoinAttachmentsTo($Data, $Attachments); if ($Data2) { $this->JoinAttachmentsTo($Data2, $Attachments); } }
/** * Rebuilds the category tree. We are using the Nested Set tree model. * * @ref http://articles.sitepoint.com/article/hierarchical-data-database/2 * @ref http://en.wikipedia.org/wiki/Nested_set_model * * @since 2.0.0 * @access public */ public function RebuildTree() { // Grab all of the categories. $Categories = $this->SQL->Get('Category', 'TreeLeft, Sort, Name'); $Categories = Gdn_DataSet::Index($Categories->ResultArray(), 'CategoryID'); // Make sure the tree has a root. if (!isset($Categories[-1])) { $RootCat = array('CategoryID' => -1, 'TreeLeft' => 1, 'TreeRight' => 4, 'Depth' => 0, 'InsertUserID' => 1, 'UpdateUserID' => 1, 'DateInserted' => Gdn_Format::ToDateTime(), 'DateUpdated' => Gdn_Format::ToDateTime(), 'Name' => 'Root', 'UrlCode' => '', 'Description' => 'Root of category tree. Users should never see this.', 'PermissionCategoryID' => -1, 'Sort' => 0, 'ParentCategoryID' => NULL); $Categories[-1] = $RootCat; $this->SQL->Insert('Category', $RootCat); } // Build a tree structure out of the categories. $Root = NULL; foreach ($Categories as &$Cat) { if (!isset($Cat['CategoryID'])) { continue; } // Backup category settings for efficient database saving. try { $Cat['_TreeLeft'] = $Cat['TreeLeft']; $Cat['_TreeRight'] = $Cat['TreeRight']; $Cat['_Depth'] = $Cat['Depth']; $Cat['_PermissionCategoryID'] = $Cat['PermissionCategoryID']; $Cat['_ParentCategoryID'] = $Cat['ParentCategoryID']; } catch (Exception $Ex) { } if ($Cat['CategoryID'] == -1) { $Root =& $Cat; continue; } $ParentID = $Cat['ParentCategoryID']; if (!$ParentID) { $ParentID = -1; $Cat['ParentCategoryID'] = $ParentID; } if (!isset($Categories[$ParentID]['Children'])) { $Categories[$ParentID]['Children'] = array(); } $Categories[$ParentID]['Children'][] =& $Cat; } unset($Cat); // Set the tree attributes of the tree. $this->_SetTree($Root); unset($Root); // Save the tree structure. foreach ($Categories as $Cat) { if (!isset($Cat['CategoryID'])) { continue; } if ($Cat['_TreeLeft'] != $Cat['TreeLeft'] || $Cat['_TreeRight'] != $Cat['TreeRight'] || $Cat['_Depth'] != $Cat['Depth'] || $Cat['PermissionCategoryID'] != $Cat['PermissionCategoryID'] || $Cat['_ParentCategoryID'] != $Cat['ParentCategoryID'] || $Cat['Sort'] != $Cat['TreeLeft']) { $this->SQL->Put('Category', array('TreeLeft' => $Cat['TreeLeft'], 'TreeRight' => $Cat['TreeRight'], 'Depth' => $Cat['Depth'], 'PermissionCategoryID' => $Cat['PermissionCategoryID'], 'ParentCategoryID' => $Cat['ParentCategoryID'], 'Sort' => $Cat['TreeLeft']), array('CategoryID' => $Cat['CategoryID'])); } } $this->SetCache(); }
/** * Add another user to the conversation. * * @since 2.0.0 * @access public * * @param int $ConversationID Unique ID of conversation effected. * @param int $UserID Unique ID of current user. */ public function AddUserToConversation($ConversationID, $UserID) { if (!is_array($UserID)) { $UserID = array($UserID); } // First define the current users in the conversation $OldContributorData = $this->GetRecipients($ConversationID); $OldContributorData = Gdn_DataSet::Index($OldContributorData, 'UserID'); $AddedUserIDs = array(); // Get some information about this conversation $ConversationData = $this->SQL->Select('LastMessageID')->Select('CountMessages')->From('Conversation')->Where('ConversationID', $ConversationID)->Get()->FirstRow(); // Add the user(s) if they are not already in the conversation foreach ($UserID as $NewUserID) { if (!array_key_exists($NewUserID, $OldContributorData)) { $AddedUserIDs[] = $NewUserID; $this->SQL->Insert('UserConversation', array('UserID' => $NewUserID, 'ConversationID' => $ConversationID, 'LastMessageID' => $ConversationData->LastMessageID, 'CountReadMessages' => 0, 'DateConversationUpdated' => $ConversationData['DateUpdated'])); } elseif ($OldContributorData[$NewUserID]->Deleted) { $AddedUserIDs[] = $NewUserID; $this->SQL->Put('UserConversation', array('Deleted' => 0), array('ConversationID' => $ConversationID, 'UserID' => $NewUserID)); } } if (count($AddedUserIDs) > 0) { $Session = Gdn::Session(); // Update the Contributors field on the conversation $Contributors = array_unique(array_merge($AddedUserIDs, array_keys($OldContributorData))); sort($Contributors); $this->SQL->Update('Conversation')->Set('Contributors', Gdn_Format::Serialize($Contributors))->Where('ConversationID', $ConversationID)->Put(); $ActivityModel = new ActivityModel(); foreach ($AddedUserIDs as $AddedUserID) { $ActivityModel->Queue(array('ActivityType' => 'AddedToConversation', 'NotifyUserID' => $AddedUserID, 'HeadlineFormat' => T('You were added to a conversation.', '{InsertUserID,user} added {NotifyUserID,you} to a <a href="{Url,htmlencode}">conversation</a>.')), 'ConversationMessage'); } $ActivityModel->SaveQueue(); $this->UpdateUserUnreadCount($AddedUserIDs); } }
/** * * * @param $IDs * @param bool $SkipCacheQuery * @return array * @throws Exception */ public function getIDs($IDs, $SkipCacheQuery = false) { $DatabaseIDs = $IDs; $Data = array(); if (!$SkipCacheQuery) { $Keys = array(); // Make keys for cache query foreach ($IDs as $UserID) { if (!$UserID) { continue; } $Keys[] = formatString(self::USERID_KEY, array('UserID' => $UserID)); } // Query cache layer $CacheData = Gdn::cache()->get($Keys); if (!is_array($CacheData)) { $CacheData = array(); } foreach ($CacheData as $RealKey => $User) { if ($User === null) { $ResultUserID = trim(strrchr($RealKey, '.'), '.'); } else { $ResultUserID = val('UserID', $User); } $this->setCalculatedFields($User); $Data[$ResultUserID] = $User; } //echo "from cache:\n"; //print_r($Data); $DatabaseIDs = array_diff($DatabaseIDs, array_keys($Data)); unset($CacheData); } // Clean out bogus blank entries $DatabaseIDs = array_diff($DatabaseIDs, array(null, '')); // If we are missing any users from cache query, fill em up here if (sizeof($DatabaseIDs)) { $DatabaseData = $this->SQL->whereIn('UserID', $DatabaseIDs)->getWhere('User')->result(DATASET_TYPE_ARRAY); $DatabaseData = Gdn_DataSet::Index($DatabaseData, 'UserID'); //echo "from DB:\n"; //print_r($DatabaseData); foreach ($DatabaseIDs as $ID) { if (isset($DatabaseData[$ID])) { $User = $DatabaseData[$ID]; $this->userCache($User, $ID); // Apply calculated fields $this->setCalculatedFields($User); $Data[$ID] = $User; } else { $User = null; $this->userCache($User, $ID); } } } $this->EventArguments['RequestedIDs'] = $IDs; $this->EventArguments['LoadedUsers'] =& $Data; $this->fireEvent('AfterGetIDs'); return $Data; }
/** * Get all of the global permissions for one or more roles. * * @param int|array $RoleID The role(s) to get the permissions for. * @param string $LimitToSuffix Whether or not to limit the permissions to a suffix. * @return Returns an */ public function getGlobalPermissions($RoleID, $LimitToSuffix = '') { $RoleIDs = (array) $RoleID; // Get the global permissions. $Data = $this->SQL->select('*')->from('Permission p')->whereIn('p.RoleID', array_merge($RoleIDs, array(0)))->where('p.JunctionTable is null')->orderBy('p.RoleID')->get()->resultArray(); $this->_MergeDisabledPermissions($Data); $Data = Gdn_DataSet::Index($Data, 'RoleID'); $DefaultRow = $Data[0]; unset($Data[0], $DefaultRow['RoleID'], $DefaultRow['JunctionTable'], $DefaultRow['JunctionColumn'], $DefaultRow['JunctionID']); $DefaultRow = $this->StripPermissions($DefaultRow, $DefaultRow, $LimitToSuffix); if ($RoleID) { // When editing a role make sure the default permissions are false so as not to be misleading. $DefaultRow = array_fill_keys(array_keys($DefaultRow), 0); } foreach ($RoleIDs as $ID) { if (isset($Data[$ID])) { $Data[$ID] = array_intersect_key($Data[$ID], $DefaultRow); } else { $Data[$ID] = $DefaultRow; $Data[$ID]['PermissionID'] = null; } } if (count($RoleIDs) === 1) { return array_pop($Data); } else { return $Data; } }
/** * Add another user to the conversation. * * @since 2.0.0 * @access public * * @param int $ConversationID Unique ID of conversation effected. * @param int $UserID Unique ID of current user. */ public function AddUserToConversation($ConversationID, $UserID) { if (!is_array($UserID)) { $UserID = array($UserID); } // First define the current users in the conversation $OldContributorData = $this->GetRecipients($ConversationID); $OldContributorData = Gdn_DataSet::Index($OldContributorData, 'UserID'); $AddedUserIDs = array(); // Get some information about this conversation $ConversationData = $this->SQL->Select('LastMessageID')->Select('CountMessages')->From('Conversation')->Where('ConversationID', $ConversationID)->Get()->FirstRow(); // Add the user(s) if they are not already in the conversation foreach ($UserID as $NewUserID) { if (!array_key_exists($NewUserID, $OldContributorData)) { $AddedUserIDs[] = $NewUserID; $this->SQL->Insert('UserConversation', array('UserID' => $NewUserID, 'ConversationID' => $ConversationID, 'LastMessageID' => $ConversationData->LastMessageID, 'CountReadMessages' => 0)); } elseif ($OldContributorData[$NewUserID]->Deleted) { $AddedUserIDs[] = $NewUserID; $this->SQL->Put('UserConversation', array('Deleted' => 0), array('ConversationID' => $ConversationID, 'UserID' => $NewUserID)); } } if (count($AddedUserIDs) > 0) { $Session = Gdn::Session(); // Update the Contributors field on the conversation $Contributors = array_unique(array_merge($AddedUserIDs, array_keys($OldContributorData))); sort($Contributors); $this->SQL->Update('Conversation')->Set('Contributors', Gdn_Format::Serialize($Contributors))->Where('ConversationID', $ConversationID)->Put(); foreach ($AddedUserIDs as $AddedUserID) { // And notify them that they were added to the conversation AddActivity($Session->UserID, 'AddedToConversation', '', $AddedUserID, '/messages/' . $ConversationID); } $this->UpdateUserUnreadCount($AddedUserIDs); } }
public static function SetUserRoles(&$Users, $UserIDColumn = 'UserID', $RolesColumn = 'Roles') { $UserIDs = array_unique(ConsolidateArrayValuesByKey($Users, $UserIDColumn)); // Try and get all of the mappings from the cache. $Keys = array(); foreach ($UserIDs as $UserID) { $Keys[$UserID] = FormatString(UserModel::USERROLES_KEY, array('UserID' => $UserID)); } $UserRoles = Gdn::Cache()->Get($Keys); if (!is_array($UserRoles)) { $UserRoles = array(); } // Grab all of the data that doesn't exist from the DB. $MissingIDs = array(); foreach ($Keys as $UserID => $Key) { if (!array_key_exists($Key, $UserRoles)) { $MissingIDs[$UserID] = $Key; } } if (count($MissingIDs) > 0) { $DbUserRoles = Gdn::SQL()->Select('ur.*')->From('UserRole ur')->WhereIn('ur.UserID', array_keys($MissingIDs))->Get()->ResultArray(); $DbUserRoles = Gdn_DataSet::Index($DbUserRoles, 'UserID', array('Unique' => FALSE)); // Store the user role mappings. foreach ($DbUserRoles as $UserID => $Rows) { $RoleIDs = ConsolidateArrayValuesByKey($Rows, 'RoleID'); $Key = $Keys[$UserID]; Gdn::Cache()->Store($Key, $RoleIDs); $UserRoles[$Key] = $RoleIDs; } } $AllRoles = self::Roles(); // roles indexed by role id. // Join the users. foreach ($Users as &$User) { $UserID = GetValue($UserIDColumn, $User); $Key = $Keys[$UserID]; $RoleIDs = GetValue($Key, $UserRoles, array()); $Roles = array(); foreach ($RoleIDs as $RoleID) { if (!array_key_exists($RoleID, $AllRoles)) { continue; } $Roles[$RoleID] = $AllRoles[$RoleID]['Name']; } SetValue($RolesColumn, $User, $Roles); } }
/** * Join the tags to a set of discussions. * @param $data */ public function joinTags(&$data) { $ids = array(); foreach ($data as $row) { $discussionId = val('DiscussionID', $row); if ($discussionId) { $ids[] = $discussionId; } } // Select the tags. $all_tags = $this->SQL->Select('td.DiscussionID, t.TagID, t.Name, t.FullName')->From('TagDiscussion td')->Join('Tag t', 't.TagID = td.TagID')->WhereIn('td.DiscussionID', $ids)->Get()->ResultArray(); $all_tags = Gdn_DataSet::Index($all_tags, 'DiscussionID', array('Unique' => FALSE)); foreach ($data as &$row) { $discussionId = val('DiscussionID', $row); if (isset($all_tags[$discussionId])) { $tags = $all_tags[$discussionId]; if ($this->StringTags) { $tags = ConsolidateArrayValuesByKey($tags, 'Name'); SetValue('Tags', $row, implode(',', $tags)); } else { foreach ($tags as &$trow) { unset($trow['DiscussionID']); } SetValue('Tags', $row, $tags); } } else { if ($this->StringTags) { SetValue('Tags', $row, ''); } else { SetValue('Tags', $row, array()); } } } }
public function NotifyNewDiscussion($Discussion) { if (is_numeric($Discussion)) { $Discussion = $this->GetID($Discussion); } // Grab all of the users that need to be notified. $Data = $this->SQL->GetWhere('UserMeta', array('Name' => 'Preferences.Email.NewDiscussion'))->ResultArray(); // Grab all of their follow/unfollow preferences. $UserIDs = ConsolidateArrayValuesByKey($Data, 'UserID'); $CategoryID = $Discussion['CategoryID']; $UserPrefs = $this->SQL->Select('*')->From('UserCategory')->Where('CategoryID', $CategoryID)->WhereIn('UserID', $UserIDs)->Get()->ResultArray(); $UserPrefs = Gdn_DataSet::Index($UserPrefs, 'UserID'); foreach ($Data as $Row) { $UserID = $Row['UserID']; if ($UserID == $Discussion['InsertUserID']) { continue; } if (array_key_exists($UserID, $UserPrefs) && $UserPrefs[$UserID]['Unfollow']) { continue; } AddActivity($Discussion['InsertUserID'], 'NewDiscussion', Anchor(Gdn_Format::Text($Discussion['Name']), ExternalUrl('discussion/' . $Discussion['DiscussionID'] . '/' . Gdn_Format::Url($Discussion['Name']))), $UserID, '/discussion/' . $Discussion['DiscussionID'] . '/' . Gdn_Format::Url($Discussion['Name']), TRUE); } }
/** * Add the tag input to the discussion form. * @param Gdn_Controller $Sender */ public function PostController_AfterDiscussionFormOptions_Handler($Sender) { if (in_array($Sender->RequestMethod, array('discussion', 'editdiscussion', 'question'))) { // Setup, get most popular tags $TagModel = TagModel::instance(); $Tags = $TagModel->GetWhere(array('Type' => array_keys($TagModel->defaultTypes())), 'CountDiscussions', 'desc', C('Plugins.Tagging.ShowLimit', 50))->Result(DATASET_TYPE_ARRAY); $TagsHtml = count($Tags) ? '' : T('No tags have been created yet.'); $Tags = Gdn_DataSet::Index($Tags, 'FullName'); ksort($Tags); // The tags must be fetched. if ($Sender->Request->IsPostBack()) { $tag_ids = TagModel::SplitTags($Sender->Form->GetFormValue('Tags')); $tags = TagModel::instance()->GetWhere(array('TagID' => $tag_ids))->ResultArray(); $tags = ConsolidateArrayValuesByKey($tags, 'FullName', 'TagID'); } else { // The tags should be set on the data. $tags = ConsolidateArrayValuesByKey($Sender->Data('Tags', array()), 'TagID', 'FullName'); $xtags = $Sender->Data('XTags', array()); foreach (TagModel::instance()->defaultTypes() as $key => $row) { if (isset($xtags[$key])) { $xtags2 = ConsolidateArrayValuesByKey($xtags[$key], 'TagID', 'FullName'); foreach ($xtags2 as $id => $name) { $tags[$id] = $name; } } } } echo '<div class="Form-Tags P">'; // Tag text box echo $Sender->Form->Label('Tags', 'Tags'); echo $Sender->Form->TextBox('Tags', array('data-tags' => json_encode($tags))); // Available tags echo Wrap(Anchor(T('Show popular tags'), '#'), 'span', array('class' => 'ShowTags')); foreach ($Tags as $Tag) { $TagsHtml .= Anchor(htmlspecialchars($Tag['FullName']), '#', 'AvailableTag', array('data-name' => $Tag['Name'], 'data-id' => $Tag['TagID'])) . ' '; } echo Wrap($TagsHtml, 'div', array('class' => 'Hidden AvailableTags')); echo '</div>'; } }
/** * Record advanced notifications for users. * * @param ActivityModel $ActivityModel * @param array $Discussion * @param int $CommentID * @param array $NotifiedUsers */ public function RecordAdvancedNotications($ActivityModel, $Discussion, $Comment, &$NotifiedUsers) { // Grab all of the users that need to be notified. $Data = $this->SQL->GetWhere('UserMeta', array('Name' => 'Preferences.Email.NewDiscussion'))->ResultArray(); // Grab all of their follow/unfollow preferences. $UserIDs = ConsolidateArrayValuesByKey($Data, 'UserID'); $CategoryID = GetValue('CategoryID', $Discussion); $UserPrefs = $this->SQL->Select('*')->From('UserCategory')->Where('CategoryID', $CategoryID)->WhereIn('UserID', $UserIDs)->Get()->ResultArray(); $UserPrefs = Gdn_DataSet::Index($UserPrefs, 'UserID'); $CommentID = $Comment['CommentID']; foreach ($UserIDs as $UserID) { // if ($UserID == $Comment['InsertUserID']) // continue; if (in_array($UserID, $NotifiedUsers)) { continue; } if (array_key_exists($UserID, $UserPrefs) && $UserPrefs[$UserID]['Unfollow']) { continue; } $ActivityID = AddActivity($Comment['InsertUserID'], 'NewComment', Gdn_Format::Text(Gdn_Format::To($Comment['Body'], $Comment['Format'])), $UserID, "/discussion/comment/{$CommentID}#Comment_{$CommentID}", TRUE); // $ActivityModel->QueueNotification($ActivityID); $NotifiedUsers[] = $UserID; } }
/** * Form to ask for the destination of the move, confirmation and permission check. */ public function confirmDiscussionMoves($DiscussionID = null) { $Session = Gdn::session(); $this->Form = new Gdn_Form(); $DiscussionModel = new DiscussionModel(); $CategoryModel = new CategoryModel(); $this->title(t('Confirm')); if ($DiscussionID) { $CheckedDiscussions = (array) $DiscussionID; $ClearSelection = false; } else { $CheckedDiscussions = Gdn::userModel()->getAttribute($Session->User->UserID, 'CheckedDiscussions', array()); if (!is_array($CheckedDiscussions)) { $CheckedDiscussions = array(); } $ClearSelection = true; } $DiscussionIDs = $CheckedDiscussions; $CountCheckedDiscussions = count($DiscussionIDs); $this->setData('CountCheckedDiscussions', $CountCheckedDiscussions); // Check for edit permissions on each discussion $AllowedDiscussions = array(); $DiscussionData = $DiscussionModel->SQL->select('DiscussionID, Name, DateLastComment, CategoryID, CountComments')->from('Discussion')->whereIn('DiscussionID', $DiscussionIDs)->get(); $DiscussionData = Gdn_DataSet::Index($DiscussionData->resultArray(), array('DiscussionID')); foreach ($DiscussionData as $DiscussionID => $Discussion) { $Category = CategoryModel::categories($Discussion['CategoryID']); if ($Category && $Category['PermsDiscussionsEdit']) { $AllowedDiscussions[] = $DiscussionID; } } $this->setData('CountAllowed', count($AllowedDiscussions)); $CountNotAllowed = $CountCheckedDiscussions - count($AllowedDiscussions); $this->setData('CountNotAllowed', $CountNotAllowed); if ($this->Form->authenticatedPostBack()) { // Retrieve the category id $CategoryID = $this->Form->getFormValue('CategoryID'); $Category = CategoryModel::categories($CategoryID); $RedirectLink = $this->Form->getFormValue('RedirectLink'); // User must have add permission on the target category if (!$Category['PermsDiscussionsAdd']) { throw forbiddenException('@' . t('You do not have permission to add discussions to this category.')); } $AffectedCategories = array(); // Iterate and move. foreach ($AllowedDiscussions as $DiscussionID) { $Discussion = val($DiscussionID, $DiscussionData); // Create the shadow redirect. if ($RedirectLink) { $DiscussionModel->defineSchema(); $MaxNameLength = val('Length', $DiscussionModel->Schema->GetField('Name')); $RedirectDiscussion = array('Name' => SliceString(sprintf(t('Moved: %s'), $Discussion['Name']), $MaxNameLength), 'DateInserted' => $Discussion['DateLastComment'], 'Type' => 'redirect', 'CategoryID' => $Discussion['CategoryID'], 'Body' => formatString(t('This discussion has been <a href="{url,html}">moved</a>.'), array('url' => DiscussionUrl($Discussion))), 'Format' => 'Html', 'Closed' => true); // Pass a forced input formatter around this exception. if (c('Garden.ForceInputFormatter')) { $InputFormat = c('Garden.InputFormatter'); saveToConfig('Garden.InputFormatter', 'Html', false); } $RedirectID = $DiscussionModel->save($RedirectDiscussion); // Reset the input formatter if (c('Garden.ForceInputFormatter')) { saveToConfig('Garden.InputFormatter', $InputFormat, false); } if (!$RedirectID) { $this->Form->setValidationResults($DiscussionModel->validationResults()); break; } } $DiscussionModel->setField($DiscussionID, 'CategoryID', $CategoryID); if (!isset($AffectedCategories[$Discussion['CategoryID']])) { $AffectedCategories[$Discussion['CategoryID']] = array(-1, -$Discussion['CountComments']); } else { $AffectedCategories[$Discussion['CategoryID']][0] -= 1; $AffectedCategories[$Discussion['CategoryID']][1] -= $Discussion['CountComments']; } if (!isset($AffectedCategories[$CategoryID])) { $AffectedCategories[$CategoryID] = array(1, $Discussion['CountComments']); } else { $AffectedCategories[$CategoryID][0] += 1; $AffectedCategories[$CategoryID][1] += $Discussion['CountComments']; } } // Update recent posts and counts on all affected categories. foreach ($AffectedCategories as $CategoryID => $Counts) { $CategoryModel->SetRecentPost($CategoryID); $CategoryModel->SQL->update('Category')->set('CountDiscussions', 'CountDiscussions' . ($Counts[0] < 0 ? ' - ' : ' + ') . abs($Counts[0]), false)->set('CountComments', 'CountComments' . ($Counts[1] < 0 ? ' - ' : ' + ') . abs($Counts[1]), false)->where('CategoryID', $CategoryID)->put(); } // Clear selections. if ($ClearSelection) { Gdn::userModel()->saveAttribute($Session->UserID, 'CheckedDiscussions', false); ModerationController::InformCheckedDiscussions($this); } if ($this->Form->errorCount() == 0) { $this->jsonTarget('', '', 'Refresh'); } } $this->render(); }
/** * Join external records to an array. * * @param array &$Data The data to join. * In order to join records each row must have the a RecordType and RecordID column. * @param string $Column The name of the column to put the record in. * If this is blank then the record will be merged into the row. * @param bool $Unset Whether or not to unset rows that don't have a record. * @since 2.3 */ function joinRecords(&$Data, $Column = '', $Unset = false) { $IDs = array(); $AllowedCats = DiscussionModel::CategoryPermissions(); if ($AllowedCats === false) { // This user does not have permission to view anything. $Data = array(); return; } // Gather all of the ids to fetch. foreach ($Data as &$Row) { if (!$Row['RecordType']) { continue; } $RecordType = ucfirst(StringEndsWith($Row['RecordType'], '-Total', true, true)); $Row['RecordType'] = $RecordType; $ID = $Row['RecordID']; $IDs[$RecordType][$ID] = $ID; } // Fetch all of the data in turn. $JoinData = array(); foreach ($IDs as $RecordType => $RecordIDs) { if ($RecordType == 'Comment') { Gdn::SQL()->Select('d.Name, d.CategoryID')->Join('Discussion d', 'd.DiscussionID = r.DiscussionID'); } $Rows = Gdn::SQL()->Select('r.*')->WhereIn($RecordType . 'ID', array_values($RecordIDs))->Get($RecordType . ' r')->ResultArray(); $JoinData[$RecordType] = Gdn_DataSet::Index($Rows, array($RecordType . 'ID')); } // Join the rows. $Unsets = array(); foreach ($Data as $Index => &$Row) { $RecordType = $Row['RecordType']; $ID = $Row['RecordID']; if (!isset($JoinData[$RecordType][$ID])) { if ($Unset) { $Unsets[] = $Index; } continue; // orphaned? } $Record = $JoinData[$RecordType][$ID]; if ($AllowedCats !== true) { // Check to see if the user has permission to view this record. $CategoryID = GetValue('CategoryID', $Record, -1); if (!in_array($CategoryID, $AllowedCats)) { $Unsets[] = $Index; continue; } } switch ($RecordType) { case 'Discussion': $Url = DiscussionUrl($Record, '', '/') . '#latest'; break; case 'Comment': $Url = CommentUrl($Record, '/'); $Record['Name'] = sprintf(T('Re: %s'), $Record['Name']); break; default: $Url = ''; } $Record['Url'] = $Url; if ($Column) { $Row[$Column] = $Record; } else { $Row = array_merge($Row, $Record); } } foreach ($Unsets as $Index) { unset($Data[$Index]); } // Join the users. Gdn::UserModel()->JoinUsers($Data, array('InsertUserID')); if (!empty($Unsets)) { $Data = array_values($Data); } }
/** * * * @param $Users * @param string $UserIDColumn * @param string $RolesColumn */ public static function setUserRoles(&$Users, $UserIDColumn = 'UserID', $RolesColumn = 'Roles') { $UserIDs = array_unique(ConsolidateArrayValuesByKey($Users, $UserIDColumn)); // Try and get all of the mappings from the cache. $Keys = array(); foreach ($UserIDs as $UserID) { $Keys[$UserID] = formatString(UserModel::USERROLES_KEY, array('UserID' => $UserID)); } $UserRoles = Gdn::cache()->get($Keys); if (!is_array($UserRoles)) { $UserRoles = array(); } // Grab all of the data that doesn't exist from the DB. $MissingIDs = array(); foreach ($Keys as $UserID => $Key) { if (!array_key_exists($Key, $UserRoles)) { $MissingIDs[$UserID] = $Key; } } if (count($MissingIDs) > 0) { $DbUserRoles = Gdn::sql()->select('ur.*')->from('UserRole ur')->whereIn('ur.UserID', array_keys($MissingIDs))->get()->resultArray(); $DbUserRoles = Gdn_DataSet::Index($DbUserRoles, 'UserID', array('Unique' => false)); // Store the user role mappings. foreach ($DbUserRoles as $UserID => $Rows) { $RoleIDs = consolidateArrayValuesByKey($Rows, 'RoleID'); $Key = $Keys[$UserID]; Gdn::cache()->store($Key, $RoleIDs); $UserRoles[$Key] = $RoleIDs; } } $AllRoles = self::roles(); // roles indexed by role id. // Skip personal info roles if (!checkPermission('Garden.PersonalInfo.View')) { $AllRoles = array_filter($AllRoles, 'self::FilterPersonalInfo'); } // Join the users. foreach ($Users as &$User) { $UserID = val($UserIDColumn, $User); $Key = $Keys[$UserID]; $RoleIDs = val($Key, $UserRoles, array()); $Roles = array(); foreach ($RoleIDs as $RoleID) { if (!array_key_exists($RoleID, $AllRoles)) { continue; } $Roles[$RoleID] = $AllRoles[$RoleID]['Name']; } setValue($RolesColumn, $User, $Roles); } }
public static function Messages($ID = FALSE) { if ($ID === NULL) { Gdn::Cache()->Remove('Messages'); return; } $Messages = Gdn::Cache()->Get('Messages'); if ($Messages === Gdn_Cache::CACHEOP_FAILURE) { $Messages = Gdn::SQL()->Get('Message', 'Sort')->ResultArray(); $Messages = Gdn_DataSet::Index($Messages, array('MessageID')); Gdn::Cache()->Store('Messages', $Messages); } if ($ID === FALSE) { return $Messages; } else { return GetValue($ID, $Messages); } }
public static function SetUserRoles(&$Users, $UserIDColumn = 'UserID', $RolesColumn = 'Roles') { $UserIDs = ConsolidateArrayValuesByKey($Users, $UserIDColumn); $UserRoles = Gdn::SQL() ->Select('ur.UserID, ur.RoleID, r.Name') ->From('UserRole ur') ->Join('Role r', 'ur.RoleID = r.RoleID') ->WhereIn('ur.UserID', $UserIDs) ->Get()->ResultArray(); $UserRoles = Gdn_DataSet::Index($UserRoles, 'UserID', array('Unique' => FALSE)); foreach ($Users as &$User) { $UserID = GetValue($UserIDColumn, $User); $Roles = GetValue($UserID, $UserRoles, array()); $Roles = ConsolidateArrayValuesByKey($Roles, 'RoleID', 'Name'); SetValue($RolesColumn, $User, $Roles); } }
/** * Join message counts into the discussion list. * @param DiscussionModel $Sender * @param array $Args */ public function DiscussionModel_AfterAddColumns_Handler($Sender, $Args) { if (!Gdn::Session()->UserID) { return; } $Data = $Args['Data']; $Result =& $Data->Result(); // Gather the discussion IDs. $DiscusisonIDs = array(); foreach ($Result as $Row) { $DiscusisonIDs[] = GetValue('DiscussionID', $Row); } // Grab all of the whispers associated to the discussions being looked at. $Sql = Gdn::SQL()->Select('c.DiscussionID')->Select('c.CountMessages', 'sum', 'CountMessages')->Select('c.DateUpdated', 'max', 'DateLastMessage')->From('Conversation c')->WhereIn('c.DiscussionID', $DiscusisonIDs)->GroupBy('c.DiscussionID'); if (!Gdn::Session()->CheckPermission('Conversations.Moderation.Manage')) { $Sql->Join('UserConversation uc', 'c.ConversationID = uc.ConversationID')->Where('uc.UserID', Gdn::Session()->UserID); } $Conversations = $Sql->Get()->ResultArray(); $Conversations = Gdn_DataSet::Index($Conversations, 'DiscussionID'); foreach ($Result as &$Row) { $DiscusisonID = GetValue('DiscussionID', $Row); $CRow = GetValue($DiscusisonID, $Conversations); if (!$CRow) { continue; } $DateLastViewed = GetValue('DateLastViewed', $Row); $DateLastMessage = $CRow['DateLastMessage']; $NewWhispers = Gdn_Format::ToTimestamp($DateLastViewed) < Gdn_Format::ToTimestamp($DateLastMessage); SetValue('CountWhispers', $Row, $CRow['CountMessages']); SetValue('DateLastWhisper', $Row, $DateLastMessage); SetValue('NewWhispers', $Row, $NewWhispers); } }
/** * Get all of the global permissions for one or more roles. * * @param int|array $RoleID The role(s) to get the permissions for. * @param string $LimitToSuffix Whether or not to limit the permissions to a suffix. * @return Returns an */ public function GetGlobalPermissions($RoleID, $LimitToSuffix = '') { $RoleIDs = (array) $RoleID; // Get the global permissions. $Data = $this->SQL->Select('*')->From('Permission p')->WhereIn('p.RoleID', array_merge($RoleIDs, array(0)))->Where('p.JunctionTable is null')->OrderBy('p.RoleID')->Get()->ResultArray(); $this->_MergeDisabledPermissions($Data); $Data = Gdn_DataSet::Index($Data, 'RoleID'); $DefaultRow = $Data[0]; unset($Data[0], $DefaultRow['RoleID'], $DefaultRow['JunctionTable'], $DefaultRow['JunctionColumn'], $DefaultRow['JunctionID']); $DefaultRow = $this->StripPermissions($DefaultRow, $DefaultRow, $LimitToSuffix); foreach ($RoleIDs as $RoleID) { if (isset($Data[$RoleID])) { $Data[$RoleID] = array_intersect_key($Data[$RoleID], $DefaultRow); } else { $Data[$RoleID] = $DefaultRow; $Data[$RoleID]['PermissionID'] = NULL; } } if (count($RoleIDs) === 1) { return array_pop($Data); } else { return $Data; } }