public function __construct($Number, &$Mailbox) { $this->Mailbox =& $Mailbox; $Connection =& $this->Mailbox->Connection; $Tmp = imap_fetch_overview($Connection, $Number); $this->Overview = $Tmp[0]; $this->Structure = imap_fetchstructure($Connection, $Number); $this->HeaderInfo = imap_headerinfo($Connection, $Number); $this->MailDateTime = Gdn_Format::ToDateTime($this->HeaderInfo->udate); $this->Number = $this->Overview->msgno; $this->Uid = $this->Overview->uid; $this->RetrieveInfo(); $this->RetrieveBodyText(); $this->RetrieveAttachments(); return $this; }
/** * Grabs all new notifications and adds them to the sender's inform queue. * * This method gets called by dashboard's hooks file to display new * notifications on every pageload. * * @since 2.0.18 * @access public * * @param Gdn_Controller $Sender The object calling this method. */ public static function InformNotifications($Sender) { $Session = Gdn::Session(); if (!$Session->IsValid()) { return; } $ActivityModel = new ActivityModel(); // Get five pending notifications. $Where = array('NotifyUserID' => Gdn::Session()->UserID, 'Notified' => ActivityModel::SENT_PENDING); // If we're in the middle of a visit only get very recent notifications. $Where['DateUpdated >'] = Gdn_Format::ToDateTime(strtotime('-5 minutes')); $Activities = $ActivityModel->GetWhere($Where, 0, 5)->ResultArray(); $ActivityIDs = ConsolidateArrayValuesByKey($Activities, 'ActivityID'); $ActivityModel->SetNotified($ActivityIDs); foreach ($Activities as $Activity) { if ($Activity['Photo']) { $UserPhoto = Anchor(Img($Activity['Photo'], array('class' => 'ProfilePhotoMedium')), $Activity['Url'], 'Icon'); } else { $UserPhoto = ''; } $Excerpt = Gdn_Format::Display($Activity['Story']); $ActivityClass = ' Activity-' . $Activity['ActivityType']; $Sender->InformMessage($UserPhoto . Wrap($Activity['Headline'], 'div', array('class' => 'Title')) . Wrap($Excerpt, 'div', array('class' => 'Excerpt')), 'Dismissable AutoDismiss' . $ActivityClass . ($UserPhoto == '' ? '' : ' HasIcon')); } }
public function SetWatch($Discussion, $Limit, $Offset, $TotalComments) { // Record the user's watch data $Session = Gdn::Session(); if ($Session->UserID > 0) { $CountWatch = $Limit + $Offset; if ($CountWatch > $TotalComments) { $CountWatch = $TotalComments; } if (is_numeric($Discussion->CountCommentWatch)) { // Update the watch data if ($CountWatch != $Discussion->CountCommentWatch && $CountWatch > $Discussion->CountCommentWatch) { // Only update the watch if there are new comments. $this->SQL->Put('UserDiscussion', array('CountComments' => $CountWatch, 'DateLastViewed' => Gdn_Format::ToDateTime()), array('UserID' => $Session->UserID, 'DiscussionID' => $Discussion->DiscussionID)); } } else { // Make sure the discussion isn't archived. $ArchiveDate = Gdn::Config('Vanilla.Archive.Date'); if (!$ArchiveDate || Gdn_Format::ToTimestamp($Discussion->DateLastComment) > Gdn_Format::ToTimestamp($ArchiveDate)) { // Insert watch data $this->SQL->Insert('UserDiscussion', array('UserID' => $Session->UserID, 'DiscussionID' => $Discussion->DiscussionID, 'CountComments' => $CountWatch, 'DateLastViewed' => Gdn_Format::ToDateTime())); } } } }
public function Expire() { $ExpireBans = Gdn::SQL()->Select('Count(UserID)')->From('User')->Where(array('Banned' => TRUE, 'BanExpire<' => Gdn_Format::ToDateTime()))->Get()->Result(); if ($ExpireBans) { Gdn::SQL()->Put('User', array('Banned' => FALSE, 'BanExpire' => NULL), array('Banned' => TRUE, 'BanExpire<' => Gdn_Format::ToDateTime())); } }
protected function _CacheOnlineUserss(&$Sender) { //logic taken from Who's Online plugin $SQL = Gdn::SQL(); // $this->_OnlineUsers = $SQL // insert or update entry into table $Session = Gdn::Session(); $Invisible = $Invisible ? 1 : 0; if ($Session->UserID) { $SQL->Replace('Whosonline', array('UserID' => $Session->UserID, 'Timestamp' => Gdn_Format::ToDateTime(), 'Invisible' => $Invisible), array('UserID' => $Session->UserID)); } $Frequency = C('WhosOnline.Frequency', 4); $History = time() - $Frequency; $SQL->Select('u.UserID, u.Name, w.Timestamp, w.Invisible')->From('Whosonline w')->Join('User u', 'w.UserID = u.UserID')->Where('w.Timestamp >=', date('Y-m-d H:i:s', $History))->OrderBy('u.Name'); if (!$Session->CheckPermission('Plugins.WhosOnline.ViewHidden')) { $SQL->Where('w.Invisible', 0); } $OnlineUsers = $SQL->Get(); $arrOnline = array(); if ($OnlineUsers->NumRows() > 0) { foreach ($OnlineUsers->Result() as $User) { $arrOnline[] = $User->UserID; } } $Sender->SetData('Plugin-OnlineUsers-Marker', $arrOnline); }
/** * Checks the local Steam Profile cache for existing user profile * information. If found, serve it up. If not found, attempt to fetch * it from the Steam Community website. * * @param string $SteamID A sixty-four bit integer representing the target Steam ID * @return mixed SimpleXMLElement on success, FALSE on failure */ public function GetByID($SteamID) { // Verify that the ID is only digits and that we have SimpleXML capabilities if (preg_match('/\\d+/', $SteamID) && function_exists('simplexml_load_file')) { /** * Check to see if there are any cached profile records matching the ID and are * more than five minutes old */ $CachedProfile = $this->SQL->Select()->From('SteamProfileCache')->Where('SteamID64', $SteamID)->Where('DateRetrieved >', Gdn_Format::ToDateTime(strtotime('-5 minutes')))->Get()->Firstrow(); // Any cached entries? if ($CachedProfile) { // ...if so, load up the profile XML into a SimpleXMLElement... $CommunityProfile = simplexml_load_string($CachedProfile->ProfileXML, 'SimpleXMLElement', LIBXML_NOCDATA); // set the DateRetrieved of the cached record and go $CommunityProfile->DateRetrieved = $CachedProfile->DateRetrieved; return $CommunityProfile; } else { // ...if not, attempt to grab the profile's XML $CommunityProfile = simplexml_load_file('http://steamcommunity.com/profiles/' . $SteamID . '?xml=1', 'SimpleXMLElement', LIBXML_NOCDATA); // Were we able to successfully fetch the profile? if ($CommunityProfile && !isset($CommunityProfile->error)) { // ...if so, insert or update the profile XML into the cache table $this->SQL->Replace('SteamProfileCache', array('SteamID64' => $SteamID, 'ProfileXML' => $CommunityProfile->asXML(), 'DateRetrieved' => Gdn_Format::ToDateTime()), array('SteamID64' => $SteamID), TRUE); // Set the DateRetrieved record to now and go $CommunityProfile->DateRetrieved = Gdn_Format::ToDateTime(); return $CommunityProfile; } } } // If we hit this point, something bad has happened. return FALSE; }
/** * Checks to see if the user is spamming. Returns TRUE if the user is spamming. */ public function CheckForSpam($Type) { $Spam = FALSE; if (!in_array($Type, array('Comment', 'Discussion'))) { trigger_error(ErrorMessage(sprintf('Spam check type unknown: %s', $Type), 'VanillaModel', 'CheckForSpam'), E_USER_ERROR); } $Session = Gdn::Session(); $CountSpamCheck = $Session->GetAttribute('Count' . $Type . 'SpamCheck', 0); $DateSpamCheck = $Session->GetAttribute('Date' . $Type . 'SpamCheck', 0); $SecondsSinceSpamCheck = time() - Gdn_Format::ToTimestamp($DateSpamCheck); $SpamCount = Gdn::Config('Vanilla.' . $Type . '.SpamCount'); if (!is_numeric($SpamCount) || $SpamCount < 2) { $SpamCount = 2; } // 2 spam minimum $SpamTime = Gdn::Config('Vanilla.' . $Type . '.SpamTime'); if (!is_numeric($SpamTime) || $SpamTime < 0) { $SpamTime = 30; } // 30 second minimum spam span $SpamLock = Gdn::Config('Vanilla.' . $Type . '.SpamLock'); if (!is_numeric($SpamLock) || $SpamLock < 30) { $SpamLock = 30; } // 30 second minimum lockout // Definition: // Users cannot post more than $SpamCount comments within $SpamTime // seconds or their account will be locked for $SpamLock seconds. // Apply a spam lock if necessary $Attributes = array(); if ($SecondsSinceSpamCheck < $SpamLock && $CountSpamCheck >= $SpamCount && $DateSpamCheck !== FALSE) { // TODO: REMOVE DEBUGGING INFO AFTER THIS IS WORKING PROPERLY /* echo '<div>SecondsSinceSpamCheck: '.$SecondsSinceSpamCheck.'</div>'; echo '<div>SpamLock: '.$SpamLock.'</div>'; echo '<div>CountSpamCheck: '.$CountSpamCheck.'</div>'; echo '<div>SpamCount: '.$SpamCount.'</div>'; echo '<div>DateSpamCheck: '.$DateSpamCheck.'</div>'; echo '<div>SpamTime: '.$SpamTime.'</div>'; */ $Spam = TRUE; $this->Validation->AddValidationResult('Body', sprintf(T('You have posted %1$s times within %2$s seconds. A spam block is now in effect on your account. You must wait at least %3$s seconds before attempting to post again.'), $SpamCount, $SpamTime, $SpamLock)); // Update the 'waiting period' every time they try to post again $Attributes['Date' . $Type . 'SpamCheck'] = Gdn_Format::ToDateTime(); } else { if ($SecondsSinceSpamCheck > $SpamTime) { $Attributes['Count' . $Type . 'SpamCheck'] = 1; $Attributes['Date' . $Type . 'SpamCheck'] = Gdn_Format::ToDateTime(); } else { $Attributes['Count' . $Type . 'SpamCheck'] = $CountSpamCheck + 1; } } // Update the user profile after every comment $UserModel = Gdn::UserModel(); $UserModel->SaveAttribute($Session->UserID, $Attributes); return $Spam; }
public function Structure() { // Get a user for operations. $UserID = Gdn::SQL()->GetWhere('User', array('Name' => 'Mollom', 'Admin' => 2))->Value('UserID'); if (!$UserID) { $UserID = Gdn::SQL()->Insert('User', array('Name' => 'Mollom', 'Password' => RandomString('20'), 'HashMethod' => 'Random', 'Email' => '*****@*****.**', 'DateInserted' => Gdn_Format::ToDateTime(), 'Admin' => '2')); } SaveToConfig('Plugins.Mollom.UserID', $UserID); }
public function MarkRead($CategoryID, $TKey) { if (Gdn::Session()->ValidateTransientKey($TKey)) { $this->CategoryModel->SaveUserTree($CategoryID, array('DateMarkedRead' => Gdn_Format::ToDateTime())); } if ($this->DeliveryType() == DELIVERY_TYPE_ALL) { Redirect('/categories'); } $this->Render(); }
/** * Handle discussion option menu bump action. */ public function DiscussionController_Bump_Create($Sender, $Args) { $Sender->Permission('Garden.Moderation.Manage'); // Get discussion $DiscussionID = $Sender->Request->Get('discussionid'); $Discussion = $Sender->DiscussionModel->GetID($DiscussionID); if (!$Discussion) { throw NotFoundException('Discussion'); } // Update DateLastComment & redirect $Sender->DiscussionModel->SetProperty($DiscussionID, 'DateLastComment', Gdn_Format::ToDateTime()); Redirect(DiscussionUrl($Discussion)); }
public function DiscussionController_AutoExpire_Create($Sender, $Args) { $DiscussionID = intval($Args[0]); $DiscussionModel = new DiscussionModel(); $Discussion = $DiscussionModel->GetID($DiscussionID); if (!Gdn::Session()->CheckPermission('Vanilla.Discussions.Close', TRUE, 'Category', $Discussion->PermissionCategoryID)) { throw PermissionException('Vanilla.Discussions.Close'); } if (strtolower($Args[1]) == 'reset') { Gdn::SQL()->Put('Discussion', array('AutoExpire' => 1, 'Closed' => 0, 'DateReOpened' => Gdn_Format::ToDateTime()), array('DiscussionID' => $DiscussionID)); } else { $Expire = strtolower($Args[1]) == 'on' ? 1 : 0; Gdn::SQL()->Put('Discussion', array('AutoExpire' => $Expire), array('DiscussionID' => $DiscussionID)); } Redirect('discussion/' . $DiscussionID . '/' . Gdn_Format::Url($Discussion->Name)); }
public function GetData($Invisible = FALSE) { $SQL = Gdn::SQL(); // $this->_OnlineUsers = $SQL // insert or update entry into table $Session = Gdn::Session(); $Invisible = $Invisible ? 1 : 0; if ($Session->UserID) { $SQL->Replace('Whosonline', array('UserID' => $Session->UserID, 'Timestamp' => Gdn_Format::ToDateTime(), 'Invisible' => $Invisible), array('UserID' => $Session->UserID)); } $Frequency = C('WhosOnline.Frequency', 4); $History = time() - $Frequency; $SQL->Select('u.UserID, u.Name, w.Timestamp, w.Invisible')->From('Whosonline w')->Join('User u', 'w.UserID = u.UserID')->Where('w.Timestamp >=', date('Y-m-d H:i:s', $History))->OrderBy('u.Name'); if (!$Session->CheckPermission('Plugins.WhosOnline.ViewHidden')) { $SQL->Where('w.Invisible', 0); } $this->_OnlineUsers = $SQL->Get(); }
public function Delete($ActivityID) { // Get the activity first $Activity = $this->GetID($ActivityID); if (is_object($Activity)) { $Users = array(); $Users[] = $Activity->ActivityUserID; if (is_numeric($Activity->RegardingUserID) && $Activity->RegardingUserID > 0) { $Users[] = $Activity->RegardingUserID; } // Update the user's dateupdated field so that profile pages will not // be cached and will reflect this deletion. $this->SQL->Update('User')->Set('DateUpdated', Gdn_Format::ToDateTime())->WhereIn('UserID', $Users)->Put(); // Delete comments on the activity item parent::Delete(array('CommentActivityID' => $ActivityID), FALSE, TRUE); // Delete the activity item parent::Delete(array('ActivityID' => $ActivityID)); } }
public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $this->AddInsertFields($FormPostValues); // Validate the form posted values $MessageID = FALSE; if ($this->Validate($FormPostValues)) { $Fields = $this->Validation->SchemaValidationFields(); // All fields on the form that relate to the schema $MessageID = $this->SQL->Insert($this->Name, $Fields); $ConversationID = ArrayValue('ConversationID', $Fields, 0); // Update the conversation's DateUpdated field $this->SQL->Update('Conversation')->Set('DateUpdated', Gdn_Format::ToDateTime())->Set('UpdateUserID', $Session->UserID)->Where('ConversationID', $ConversationID)->Put(); // NOTE: INCREMENTING COUNTS INSTEAD OF GETTING ACTUAL COUNTS COULD // BECOME A PROBLEM. WATCH FOR IT. // Update the message counts for all users in the conversation $this->SQL->Update('UserConversation')->Set('CountMessages', 'CountMessages + 1', FALSE)->Where('ConversationID', $ConversationID)->Put(); $this->SQL->Update('UserConversation')->Set('CountNewMessages', 'CountNewMessages + 1', FALSE)->Where('ConversationID', $ConversationID)->Where('UserID <>', $Session->UserID)->Put(); // Update the userconversation records to reflect the most recently // added message for all users other than the one that added the // message (otherwise they would see their name/message on the // conversation list instead of the person they are conversing with). $this->SQL->Update('UserConversation')->Set('LastMessageID', $MessageID)->Where('ConversationID', $ConversationID)->Where('UserID <>', $Session->UserID)->Put(); // Update the CountUnreadConversations count on each user related to the discussion. // And notify the users of the new message $UnreadData = $this->SQL->Select('c.UserID')->Select('c2.CountNewMessages', 'count', 'CountUnreadConversations')->From('UserConversation c')->Join('UserConversation c2', 'c.UserID = c2.UserID')->Where('c2.CountNewMessages >', 0)->Where('c.ConversationID', $ConversationID)->Where('c.UserID <>', $Session->UserID)->GroupBy('c.UserID')->Get(); $ActivityModel = new ActivityModel(); foreach ($UnreadData->Result() as $User) { // Update the CountUnreadConversations count on each user related to the discussion. $this->SQL->Update('User')->Set('CountUnreadConversations', $User->CountUnreadConversations)->Where('UserID', $User->UserID)->Put(); // And notify the users of the new message $ActivityID = $ActivityModel->Add($Session->UserID, 'ConversationMessage', '', $User->UserID, '', '/messages/' . $ConversationID . '#' . $MessageID, FALSE); $Story = ArrayValue('Body', $Fields, ''); $ActivityModel->SendNotification($ActivityID, $Story); } } return $MessageID; }
/** * Add or subtract a value from a comment's score. * @param DiscussionController $Sender The controller that is implementing this method. * @param array $Args The arguments for the operation. */ public function DiscussionController_Score_Create($Sender, $Args) { $CommentID = $Args[0]; $ScoreKey = substr($Args[1], 0, 3) == 'Neg' ? -1 : 1; //$TransientKey = $Args[2]; $SQL = Gdn::SQL(); $Session = Gdn::Session(); // Get the current score for this user. $Data = $SQL->Select('uc.Score')->From('UserComment uc')->Where('uc.CommentID', $CommentID)->Where('uc.UserID', $Session->UserID)->Get()->FirstRow(); $UserScore = $Data ? $Data->Score : 0; // Get the score increments. $Inc = $this->GetScoreIncrements($CommentID, $UserScore); $Score = $Inc[$ScoreKey]; $UserScore += $Score; if ($Score != 0) { if ($Data) { // Update the score on an existing comment. $SQL->Update('UserComment')->Set('Score', $UserScore)->Set('DateUpdated', Gdn_Format::ToDateTime())->Set('UpdateUserID', $Session->UserID)->Where('UserID', $Session->UserID)->Where('CommentID', $CommentID)->Put(); } else { // Insert a new score. $SQL->Insert('UserComment', array('CommentID' => $CommentID, 'UserID' => $Session->UserID, 'Score' => $UserScore, 'DateInserted' => Gdn_Format::ToDateTime(), 'InsertUserID' => $Session->UserID, 'DateUpdated' => Gdn_Format::ToDateTime(), 'UpdateUserID' => $Session->UserID)); } // Update the comment table with the sum of the scores. $Data = $SQL->Select('uc.Score', 'sum', 'SumScore')->From('UserComment uc')->Where('uc.CommentID', $CommentID)->Get()->FirstRow(); $SumScore = $Data ? $Data->SumScore : 0; $SQL->Update('Comment')->Set('SumScore', $SumScore)->Where('CommentID', $CommentID)->Put(); $Inc = $this->GetScoreIncrements($CommentID, $UserScore); } // Redirect back where the user came from if necessary if ($Sender->DeliveryType() != DELIVERY_TYPE_BOOL) { $Target = GetIncomingValue('Target', '/vanilla/discussions/scored'); Redirect($Target); } // Send the current information back to be dealt with on the client side. $Sender->SetJson('SumScore', isset($SumScore) ? sprintf(Plural($SumScore, '%s point', '%s points'), $SumScore) : NULL); $Sender->SetJson('Inc', $Inc); $Sender->Render(); break; }
/** * Authenticates the user with the provided Authenticator class. * * @param int $UserID The UserID to start the session with. * @param bool $SetIdentity Whether or not to set the identity (cookie) or make this a one request session. */ public function Start($UserID = FALSE, $SetIdentity = TRUE) { if (!Gdn::Config('Garden.Installed')) { return; } // Retrieve the authenticated UserID from the Authenticator module. $UserModel = Gdn::Authenticator()->GetUserModel(); $this->UserID = $UserID ? $UserID : Gdn::Authenticator()->GetIdentity(); $this->User = FALSE; // Now retrieve user information if ($this->UserID > 0) { // Instantiate a UserModel to get session info $this->User = $UserModel->GetSession($this->UserID); if ($this->User) { if ($UserID && $SetIdentity) { Gdn::Authenticator()->SetIdentity($UserID); } if (Gdn::Authenticator()->ReturningUser($this->User)) { $UserModel->UpdateLastVisit($this->UserID, $this->User->Attributes, $this->User->Attributes['HourOffset']); } $UserModel->EventArguments['User'] =& $this->User; $UserModel->FireEvent('AfterGetSession'); $this->_Permissions = Gdn_Format::Unserialize($this->User->Permissions); $this->_Preferences = Gdn_Format::Unserialize($this->User->Preferences); $this->_Attributes = Gdn_Format::Unserialize($this->User->Attributes); $this->_TransientKey = is_array($this->_Attributes) ? ArrayValue('TransientKey', $this->_Attributes) : FALSE; if ($this->_TransientKey === FALSE) { $this->_TransientKey = $UserModel->SetTransientKey($this->UserID); } // If the user hasn't been active in the session-time, update their date last active $SessionLength = Gdn::Config('Garden.Session.Length', '15 minutes'); if (Gdn_Format::ToTimestamp($this->User->DateLastActive) < strtotime($SessionLength . ' ago')) { $UserModel->Save(array('UserID' => $this->UserID, 'DateLastActive' => Gdn_Format::ToDateTime())); } } else { $this->UserID = 0; $this->User = FALSE; if ($SetIdentity) { Gdn::Authenticator()->SetIdentity(NULL); } } } // Load guest permissions if necessary if ($this->UserID == 0) { $this->_Permissions = Gdn_Format::Unserialize($UserModel->DefinePermissions(0)); } }
protected function GetFileHeader() { $Now = Gdn_Format::ToDateTime(); $Result = "<?php if (!defined('APPLICATION')) exit();\n/** This file was generated by the LocaleModel on {$Now} **/\n\n"; return $Result; }
public function History($UpdateFields = TRUE, $InsertFields = FALSE) { $UserID = GetValueR('User.UserID', Gdn::Session(), Gdn::Session()->UserID); if ($InsertFields) { $this->Set('DateInserted', Gdn_Format::ToDateTime())->Set('InsertUserID', $UserID); } if ($UpdateFields) { $this->Set('DateUpdated', Gdn_Format::ToDateTime())->Set('UpdateUserID', $UserID); } return $this; }
/** * If looking at the root node, make sure it exists and that the * nested set columns exist in the table. * * @since 2.0.15 * @access public */ public function ApplyUpdates() { if (!C('Vanilla.NestedCategoriesUpdate')) { // Add new columns $Construct = Gdn::Database()->Structure(); $Construct->Table('Category')->Column('TreeLeft', 'int', TRUE)->Column('TreeRight', 'int', TRUE)->Column('Depth', 'int', TRUE)->Column('CountComments', 'int', '0')->Column('LastCommentID', 'int', TRUE)->Set(0, 0); // Insert the root node if ($this->SQL->GetWhere('Category', array('CategoryID' => -1))->NumRows() == 0) { $this->SQL->Insert('Category', 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.')); } // Build up the TreeLeft & TreeRight values. $this->RebuildTree(); SaveToConfig('Vanilla.NestedCategoriesUpdate', 1); } }
/** * Save message from form submission. * * @since 2.0.0 * @access public * * @param array $FormPostValues Values submitted via form. * @return int Unique ID of message created or updated. */ public function Save($FormPostValues, $Conversation = NULL) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $this->AddInsertFields($FormPostValues); // Validate the form posted values $MessageID = FALSE; if ($this->Validate($FormPostValues)) { $Fields = $this->Validation->SchemaValidationFields(); // All fields on the form that relate to the schema TouchValue('Format', $Fields, C('Garden.InputFormatter', 'Html')); $MessageID = $this->SQL->Insert($this->Name, $Fields); $this->LastMessageID = $MessageID; $ConversationID = ArrayValue('ConversationID', $Fields, 0); if (!$Conversation) { $Conversation = $this->SQL->GetWhere('Conversation', array('ConversationID' => $ConversationID))->FirstRow(DATASET_TYPE_ARRAY); } // Get the new message count for the conversation. $SQLR = $this->SQL->Select('MessageID', 'count', 'CountMessages')->Select('MessageID', 'max', 'LastMessageID')->From('ConversationMessage')->Where('ConversationID', $ConversationID)->Get()->FirstRow(DATASET_TYPE_ARRAY); if (sizeof($SQLR)) { list($CountMessages, $LastMessageID) = array_values($SQLR); } else { return; } // Update the conversation's DateUpdated field. $DateUpdated = Gdn_Format::ToDateTime(); $this->SQL->Update('Conversation c')->Set('CountMessages', $CountMessages)->Set('LastMessageID', $LastMessageID)->Set('UpdateUserID', Gdn::Session()->UserID)->Set('DateUpdated', $DateUpdated)->Where('ConversationID', $ConversationID)->Put(); // Update the last message of the users that were previously up-to-date on their read messages. $this->SQL->Update('UserConversation uc')->Set('uc.LastMessageID', $MessageID)->Set('uc.DateConversationUpdated', $DateUpdated)->Where('uc.ConversationID', $ConversationID)->Where('uc.Deleted', '0')->Where('uc.CountReadMessages', $CountMessages - 1)->Where('uc.UserID <>', $Session->UserID)->Put(); // Update the date updated of the users that were not up-to-date. $this->SQL->Update('UserConversation uc')->Set('uc.DateConversationUpdated', $DateUpdated)->Where('uc.ConversationID', $ConversationID)->Where('uc.Deleted', '0')->Where('uc.CountReadMessages <>', $CountMessages - 1)->Where('uc.UserID <>', $Session->UserID)->Put(); // Update the sending user. $this->SQL->Update('UserConversation uc')->Set('uc.CountReadMessages', $CountMessages)->Set('Deleted', 0)->Set('uc.DateConversationUpdated', $DateUpdated)->Where('ConversationID', $ConversationID)->Where('UserID', $Session->UserID)->Put(); // Find users involved in this conversation $UserData = $this->SQL->Select('UserID')->Select('LastMessageID')->Select('Deleted')->From('UserConversation')->Where('ConversationID', $ConversationID)->Get()->Result(DATASET_TYPE_ARRAY); $UpdateCountUserIDs = array(); $NotifyUserIDs = array(); // Collapse for call to UpdateUserCache and ActivityModel. $InsertUserFound = FALSE; foreach ($UserData as $UpdateUser) { $LastMessageID = GetValue('LastMessageID', $UpdateUser); $UserID = GetValue('UserID', $UpdateUser); $Deleted = GetValue('Deleted', $UpdateUser); if ($UserID == GetValue('InsertUserID', $Fields)) { $InsertUserFound = TRUE; if ($Deleted) { $this->SQL->Put('UserConversation', array('Deleted' => 0, 'DateConversationUpdated' => $DateUpdated), array('ConversationID' => $ConversationID, 'UserID' => $UserID)); } } // Update unread for users that were up to date if ($LastMessageID == $MessageID) { $UpdateCountUserIDs[] = $UserID; } // Send activities to users that have not deleted the conversation if (!$Deleted) { $NotifyUserIDs[] = $UserID; } } if (!$InsertUserFound) { $UserConversation = array('UserID' => GetValue('InsertUserID', $Fields), 'ConversationID' => $ConversationID, 'LastMessageID' => $LastMessageID, 'CountReadMessages' => $CountMessages, 'DateConversationUpdated' => $DateUpdated); $this->SQL->Insert('UserConversation', $UserConversation); } if (sizeof($UpdateCountUserIDs)) { $ConversationModel = new ConversationModel(); $ConversationModel->UpdateUserUnreadCount($UpdateCountUserIDs, TRUE); } $ActivityModel = new ActivityModel(); foreach ($NotifyUserIDs as $NotifyUserID) { if ($Session->UserID == $NotifyUserID) { continue; } // don't notify self. // Notify the users of the new message. $ActivityID = $ActivityModel->Add($Session->UserID, 'ConversationMessage', '', $NotifyUserID, '', "/messages/{$ConversationID}#{$MessageID}", FALSE); $Story = GetValue('Body', $Fields, ''); if (C('Conversations.Subjects.Visible')) { $Story = ConcatSep("\n\n", GetValue('Subject', $Conversation, ''), $Story); } $ActivityModel->SendNotification($ActivityID, $Story); } } return $MessageID; }
<?php if (!defined('APPLICATION')) { exit; } if (!isset($Drop)) { $Drop = FALSE; } if (!isset($Explicit)) { $Explicit = TRUE; } $SQL = $Database->SQL(); $Construct = $Database->Structure(); $Construct->Table('Category')->PrimaryKey('CategoryID')->Column('ParentCategoryID', 'int', TRUE)->Column('CountDiscussions', 'int', '0')->Column('AllowDiscussions', 'tinyint', '1')->Column('Name', 'varchar(30)')->Column('UrlCode', 'varchar(30)', TRUE)->Column('Description', 'varchar(250)', TRUE)->Column('Sort', 'int', TRUE)->Column('InsertUserID', 'int', FALSE, 'key')->Column('UpdateUserID', 'int', TRUE)->Column('DateInserted', 'datetime')->Column('DateUpdated', 'datetime')->Set($Explicit, $Drop); if ($Drop) { $SQL->Insert('Category', array('InsertUserID' => 1, 'UpdateUserID' => 1, 'DateInserted' => Gdn_Format::ToDateTime(), 'DateUpdated' => Gdn_Format::ToDateTime(), 'Name' => 'General', 'UrlCode' => 'general', 'Description' => 'General discussions', 'Sort' => '1')); } // Construct the discussion table. $Construct->Table('Discussion'); $FirstCommentIDExists = $Construct->ColumnExists('FirstCommentID'); $BodyExists = $Construct->ColumnExists('Body'); $LastCommentIDExists = $Construct->ColumnExists('LastCommentID'); $LastCommentUserIDExists = $Construct->ColumnExists('LastCommentUserID'); $CountBookmarksExists = $Construct->ColumnExists('CountBookmarks'); $Construct->PrimaryKey('DiscussionID')->Column('CategoryID', 'int', FALSE, 'key')->Column('InsertUserID', 'int', FALSE, 'key')->Column('UpdateUserID', 'int')->Column('LastCommentID', 'int', TRUE)->Column('Name', 'varchar(100)', FALSE, 'fulltext')->Column('Body', 'text', FALSE, 'fulltext')->Column('Format', 'varchar(20)', TRUE)->Column('Tags', 'varchar(255)', NULL)->Column('CountComments', 'int', '1')->Column('CountBookmarks', 'int', NULL)->Column('CountViews', 'int', '1')->Column('Closed', 'tinyint(1)', '0')->Column('Announce', 'tinyint(1)', '0')->Column('Sink', 'tinyint(1)', '0')->Column('DateInserted', 'datetime', NULL)->Column('DateUpdated', 'datetime')->Column('DateLastComment', 'datetime', NULL, 'index')->Column('LastCommentUserID', 'int', TRUE)->Column('Score', 'float', NULL)->Column('Attributes', 'text', TRUE)->Engine('MyISAM')->Set($Explicit, $Drop); // Allows the tracking of relationships between discussions and users (bookmarks, dismissed announcements, # of read comments in a discussion, etc) // Column($Name, $Type, $Length = '', $Null = FALSE, $Default = NULL, $KeyType = FALSE, $AutoIncrement = FALSE) $Construct->Table('UserDiscussion')->Column('UserID', 'int', FALSE, 'primary')->Column('DiscussionID', 'int', FALSE, array('primary', 'key'))->Column('Score', 'float', NULL)->Column('CountComments', 'int', '0')->Column('DateLastViewed', 'datetime', NULL)->Column('Dismissed', 'tinyint(1)', '0')->Column('Bookmarked', 'tinyint(1)', '0'); $Construct->Set($Explicit, $Drop); $Construct->Table('Comment')->PrimaryKey('CommentID')->Column('DiscussionID', 'int', FALSE, 'key')->Column('InsertUserID', 'int', TRUE, 'key')->Column('UpdateUserID', 'int', TRUE)->Column('DeleteUserID', 'int', TRUE)->Column('Body', 'text', FALSE, 'fulltext')->Column('Format', 'varchar(20)', TRUE)->Column('DateInserted', 'datetime', NULL, 'key')->Column('DateDeleted', 'datetime', TRUE)->Column('DateUpdated', 'datetime', TRUE)->Column('Flag', 'tinyint', 0)->Column('Score', 'float', NULL)->Column('Attributes', 'text', TRUE)->Engine('MyISAM')->Set($Explicit, $Drop); // Allows the tracking of already-read comments & votes on a per-user basis.
public function _CommentOptions($Sender, $CommentID) { $Sender->Form = new Gdn_Form(); $Comment = $Sender->CommentModel->GetID($CommentID, DATASET_TYPE_ARRAY); if (!$Comment) { throw NotFoundException('Comment'); } $Discussion = $Sender->DiscussionModel->GetID(GetValue('DiscussionID', $Comment)); $Sender->Permission('Vanilla.Discussions.Edit', TRUE, 'Category', GetValue('PermissionCategoryID', $Discussion)); if ($Sender->Form->AuthenticatedPostBack()) { $QnA = $Sender->Form->GetFormValue('QnA'); if (!$QnA) { $QnA = NULL; } $CurrentQnA = GetValue('QnA', $Comment); // ->Column('DateAccepted', 'datetime', TRUE) // ->Column('AcceptedUserID', 'int', TRUE) if ($CurrentQnA != $QnA) { $Set = array('QnA' => $QnA); if ($QnA == 'Accepted') { $Set['DateAccepted'] = Gdn_Format::ToDateTime(); $Set['AcceptedUserID'] = Gdn::Session()->UserID; } else { $Set['DateAccepted'] = NULL; $Set['AcceptedUserID'] = NULL; } $Sender->CommentModel->SetField($CommentID, $Set); $Sender->Form->SetValidationResults($Sender->CommentModel->ValidationResults()); // Determine QnA change if ($Comment['QnA'] != $QnA) { $Change = 0; switch ($QnA) { case 'Rejected': $Change = -1; if ($Comment['QnA'] != 'Accepted') { $Change = 0; } break; case 'Accepted': $Change = 1; break; default: if ($Comment['QnA'] == 'Rejected') { $Change = 0; } if ($Comment['QnA'] == 'Accepted') { $Change = -1; } break; } } // Apply change effects if ($Change) { // Update the user $UserID = GetValue('InsertUserID', $Comment); $this->RecalculateUserQnA($UserID); // Update reactions if ($this->Reactions) { include_once Gdn::Controller()->FetchViewLocation('reaction_functions', '', 'plugins/Reactions'); $Rm = new ReactionModel(); // If there's change, reactions will take care of it $Rm->React('Comment', $Comment['CommentID'], 'AcceptAnswer'); } } } // Recalculate the Q&A status of the discussion. $this->RecalculateDiscussionQnA($Discussion); Gdn::Controller()->JsonTarget('', '', 'Refresh'); } else { $Sender->Form->SetData($Comment); } $Sender->SetData('Comment', $Comment); $Sender->SetData('Discussion', $Discussion); $Sender->SetData('_QnAs', array('Accepted' => T('Yes'), 'Rejected' => T('No'), '' => T("Don't know"))); $Sender->SetData('Title', T('Q&A Options')); $Sender->Render('CommentOptions', '', 'plugins/QnA'); }
public function xIndex() { $this->AddJsFile('settings.js'); $this->Title(T('Dashboard')); $this->RequiredAdminPermissions[] = 'Garden.Settings.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Routes.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Applications.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Plugins.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Themes.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Registration.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Applicants.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Roles.Manage'; $this->RequiredAdminPermissions[] = 'Garden.Users.Add'; $this->RequiredAdminPermissions[] = 'Garden.Users.Edit'; $this->RequiredAdminPermissions[] = 'Garden.Users.Delete'; $this->RequiredAdminPermissions[] = 'Garden.Users.Approve'; $this->FireEvent('DefineAdminPermissions'); $this->Permission($this->RequiredAdminPermissions, FALSE); $this->AddSideMenu('dashboard/settings'); $UserModel = Gdn::UserModel(); // Load some data to display on the dashboard $this->BuzzData = array(); // Get the number of users in the database $CountUsers = $UserModel->GetCountLike(); $this->AddDefinition('CountUsers', $CountUsers); $this->BuzzData[T('Users')] = number_format($CountUsers); // Get the number of new users in the last day $this->BuzzData[T('New users in the last day')] = number_format($UserModel->GetCountWhere(array('DateInserted >=' => Gdn_Format::ToDateTime(strtotime('-1 day'))))); // Get the number of new users in the last week $this->BuzzData[T('New users in the last week')] = number_format($UserModel->GetCountWhere(array('DateInserted >=' => Gdn_Format::ToDateTime(strtotime('-1 week'))))); // Get recently active users $this->ActiveUserData = $UserModel->GetActiveUsers(5); // Check for updates $this->AddUpdateCheck(); // Fire an event so other applications can add some data to be displayed $this->FireEvent('DashboardData'); $this->Render(); }
/** * Update a conversation as read for a specific user id. * * @since 2.0.0 * @access public * * @param int $ConversationID Unique ID of conversation effected. * @param int $ReadingUserID Unique ID of current user. */ public function MarkRead($ConversationID, $ReadingUserID) { // Update the the read conversation count for the user. $this->SQL->Update('UserConversation uc')->Join('Conversation c', 'c.ConversationID = uc.ConversationID')->Set('uc.CountReadMessages', 'c.CountMessages', FALSE)->Set('uc.DateLastViewed', Gdn_Format::ToDateTime())->Set('uc.LastMessageID', 'c.LastMessageID', FALSE)->Where('c.ConversationID', $ConversationID)->Where('uc.ConversationID', $ConversationID)->Where('uc.UserID', $ReadingUserID)->Put(); // Also update the unread conversation count for this user $CountUnread = $this->CountUnread($ReadingUserID); // Also write through to the current session user. if ($ReadingUserID > 0 && $ReadingUserID == Gdn::Session()->UserID) { Gdn::Session()->User->CountUnreadConversations = $CountUnread; } }
/** * Update last visit. * * Regenerates other related user properties. * * @param int $UserID * @param array $Attributes * @param string|int|float $ClientHour */ function UpdateLastVisit($UserID, $Attributes, $ClientHour = '') { $UserID = (int) $UserID; if (!$UserID) { throw new Exception('A valid UserId is required.'); } $this->SQL->Update('User')->Set('DateLastActive', Gdn_Format::ToDateTime())->Set('CountVisits', 'CountVisits + 1', FALSE); if (isset($Attributes) && is_array($Attributes)) { // Generate a new transient key for the user (used to authenticate postbacks). $Attributes['TransientKey'] = RandomString(12); $this->SQL->Set('Attributes', Gdn_Format::Serialize($Attributes)); } // Set the hour offset based on the client's clock. if (is_numeric($ClientHour) && $ClientHour >= 0 && $ClientHour < 24) { $HourOffset = $ClientHour - date('G', time()); $this->SQL->Set('HourOffset', $HourOffset); } $this->SQL->Where('UserID', $UserID)->Put(); }
public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } // Get the DiscussionID from the form so we know if we are inserting or updating. $DiscussionID = ArrayValue('DiscussionID', $FormPostValues, ''); $Insert = $DiscussionID == '' ? TRUE : FALSE; if ($Insert) { unset($FormPostValues['DiscussionID']); // If no categoryid is defined, grab the first available. if (ArrayValue('CategoryID', $FormPostValues) === FALSE) { $FormPostValues['CategoryID'] = $this->SQL->Get('Category', '', '', 1)->FirstRow()->CategoryID; } $this->AddInsertFields($FormPostValues); // $FormPostValues['LastCommentUserID'] = $Session->UserID; $FormPostValues['DateLastComment'] = Gdn_Format::ToDateTime(); } // Add the update fields because this table's default sort is by DateUpdated (see $this->Get()). $this->AddUpdateFields($FormPostValues); // Remove checkboxes from the fields if they were unchecked if (ArrayValue('Announce', $FormPostValues, '') === FALSE) { unset($FormPostValues['Announce']); } if (ArrayValue('Closed', $FormPostValues, '') === FALSE) { unset($FormPostValues['Closed']); } if (ArrayValue('Sink', $FormPostValues, '') === FALSE) { unset($FormPostValues['Sink']); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, make sure the user isn't spamming if (!$Insert || !$this->CheckForSpam('Discussion')) { $Fields = $this->Validation->SchemaValidationFields(); // All fields on the form that relate to the schema $DiscussionID = intval(ArrayValue('DiscussionID', $Fields, 0)); $Fields = RemoveKeyFromArray($Fields, 'DiscussionID'); // Remove the primary key from the fields for saving $Discussion = FALSE; if ($DiscussionID > 0) { $this->SQL->Put($this->Name, $Fields, array($this->PrimaryKey => $DiscussionID)); } else { $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); $DiscussionID = $this->SQL->Insert($this->Name, $Fields); // Assign the new DiscussionID to the comment before saving $FormPostValues['IsNewDiscussion'] = TRUE; $FormPostValues['DiscussionID'] = $DiscussionID; $this->EventArguments['FormPostValues'] = $FormPostValues; $this->EventArguments['InsertFields'] = $Fields; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('AfterSaveDiscussion'); // Notify users of mentions $DiscussionName = ArrayValue('Name', $Fields, ''); $Usernames = GetMentions($DiscussionName); $UserModel = Gdn::UserModel(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { AddActivity($Session->UserID, 'DiscussionMention', '', $User->UserID, '/discussion/' . $DiscussionID . '/' . Gdn_Format::Url($DiscussionName)); } } $DiscussionName = ArrayValue('Name', $Fields, ''); $this->RecordActivity($Session->UserID, $DiscussionID, $DiscussionName); } $Data = $this->SQL->Select('CategoryID')->From('Discussion')->Where('DiscussionID', $DiscussionID)->Get(); $CategoryID = FALSE; if ($Data->NumRows() > 0) { $CategoryID = $Data->FirstRow()->CategoryID; } $this->UpdateDiscussionCount($CategoryID); } } return $DiscussionID; }
/** * Adds $this->UpdateUserID and $this->DateUpdated fields to an associative * array of fieldname/values if those fields exist on the table being * updated. * * @param array $Fields The array of fields to add the values to. */ protected function AddUpdateFields(&$Fields) { $this->DefineSchema(); if ($this->Schema->FieldExists($this->Name, $this->DateUpdated)) { if (!isset($Fields[$this->DateUpdated])) { $Fields[$this->DateUpdated] = Gdn_Format::ToDateTime(); } } $Session = Gdn::Session(); if ($Session->UserID > 0 && $this->Schema->FieldExists($this->Name, $this->UpdateUserID)) { if (!isset($Fields[$this->UpdateUserID])) { $Fields[$this->UpdateUserID] = $Session->UserID; } } if ($this->Schema->FieldExists($this->Name, 'UpdateIPAddress') && !isset($Fields['UpdateIPAddress'])) { $Fields['UpdateIPAddress'] = Gdn::Request()->IpAddress(); } }
->Column('PermissionCategoryID', 'int', '-1') // default to root. ->Column('InsertUserID', 'int', FALSE, 'key') ->Column('UpdateUserID', 'int', TRUE) ->Column('DateInserted', 'datetime') ->Column('DateUpdated', 'datetime') ->Column('LastCommentID', 'int', TRUE) ->Set($Explicit, $Drop); $RootCategoryInserted = FALSE; if ($SQL->GetWhere('Category', array('CategoryID' => -1))->NumRows() == 0) { $SQL->Insert('Category', array('CategoryID' => -1, 'TreeLeft' => 1, 'TreeRight' => 4, '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)); $RootCategoryInserted = TRUE; } if ($Drop) { $SQL->Insert('Category', array('ParentCategoryID' => -1, 'TreeLeft' => 2, 'TreeRight' => 3, 'InsertUserID' => 1, 'UpdateUserID' => 1, 'DateInserted' => Gdn_Format::ToDateTime(), 'DateUpdated' => Gdn_Format::ToDateTime(), 'Name' => 'General', 'UrlCode' => 'general', 'Description' => 'General discussions', 'PermissionCategoryID' => -1)); } elseif ($CategoryExists && !$PermissionCategoryIDExists) { if (!C('Garden.Permissions.Disabled.Category')) { // Existing installations need to be set up with per/category permissions. $SQL->Update('Category')->Set('PermissionCategoryID', 'CategoryID', FALSE)->Put(); $SQL->Update('Permission')->Set('JunctionColumn', 'PermissionCategoryID')->Where('JunctionColumn', 'CategoryID')->Put(); } } if ($CategoryExists) { $CategoryModel = new CategoryModel(); $CategoryModel->RebuildTree(); unset($CategoryModel); } // Construct the discussion table.
/** * Update user's AllViewed datetime. * * @since 1.0 * @access public */ public function UserModel_UpdateAllViewed_Create($Sender) { // Only for members $Session = Gdn::Session(); if (!$Session->IsValid()) { return; } // Can only activate on yourself $UserID = $Session->User->UserID; // Validite UserID $UserID = (int) $UserID; if (!$UserID) { throw new Exception('A valid UserId is required.'); } // Create timestamp first so all uses match. $AllViewed = Gdn_Format::ToDateTime(); // Update User timestamp $Sender->SQL->Update('User')->Set('DateAllViewed', $AllViewed)->Where('UserID', $UserID)->Put(); // Update DateLastViewed = now $Sender->SQL->Update('UserDiscussion')->Set('DateLastViewed', $AllViewed)->Where('UserID', $UserID)->Put(); // Set in current session $Session->User->DateAllViewed = Gdn_Format::ToDateTime(); }
/** * Checks to see if the user is spamming. Returns TRUE if the user is spamming. * * Users cannot post more than $SpamCount comments within $SpamTime * seconds or their account will be locked for $SpamLock seconds. * * @since 2.0.0 * @access public * @todo Remove debugging info if/when this is working correctly. * * @param string $Type Valid values are 'Comment' or 'Discussion'. * @return bool Whether spam check is positive (TRUE = spammer). */ public function CheckForSpam($Type) { $Session = Gdn::Session(); // If spam checking is disabled or user is an admin, skip $SpamCheckEnabled = GetValue('SpamCheck', $this, TRUE); if ($SpamCheckEnabled === FALSE || $Session->User->Admin || $Session->CheckPermission('Garden.Moderation.Manage')) { return FALSE; } $Spam = FALSE; // Validate $Type if (!in_array($Type, array('Comment', 'Discussion'))) { trigger_error(ErrorMessage(sprintf('Spam check type unknown: %s', $Type), 'VanillaModel', 'CheckForSpam'), E_USER_ERROR); } $CountSpamCheck = $Session->GetAttribute('Count' . $Type . 'SpamCheck', 0); $DateSpamCheck = $Session->GetAttribute('Date' . $Type . 'SpamCheck', 0); $SecondsSinceSpamCheck = time() - Gdn_Format::ToTimestamp($DateSpamCheck); // Get spam config settings $SpamCount = Gdn::Config('Vanilla.' . $Type . '.SpamCount'); if (!is_numeric($SpamCount) || $SpamCount < 1) { $SpamCount = 1; } // 1 spam minimum $SpamTime = Gdn::Config('Vanilla.' . $Type . '.SpamTime'); if (!is_numeric($SpamTime) || $SpamTime < 30) { $SpamTime = 30; } // 30 second minimum spam span $SpamLock = Gdn::Config('Vanilla.' . $Type . '.SpamLock'); if (!is_numeric($SpamLock) || $SpamLock < 60) { $SpamLock = 60; } // 60 second minimum lockout // Apply a spam lock if necessary $Attributes = array(); if ($SecondsSinceSpamCheck < $SpamLock && $CountSpamCheck >= $SpamCount && $DateSpamCheck !== FALSE) { // TODO: REMOVE DEBUGGING INFO AFTER THIS IS WORKING PROPERLY /* echo '<div>SecondsSinceSpamCheck: '.$SecondsSinceSpamCheck.'</div>'; echo '<div>SpamLock: '.$SpamLock.'</div>'; echo '<div>CountSpamCheck: '.$CountSpamCheck.'</div>'; echo '<div>SpamCount: '.$SpamCount.'</div>'; echo '<div>DateSpamCheck: '.$DateSpamCheck.'</div>'; echo '<div>SpamTime: '.$SpamTime.'</div>'; */ $Spam = TRUE; $this->Validation->AddValidationResult('Body', '@' . sprintf(T('You have posted %1$s times within %2$s seconds. A spam block is now in effect on your account. You must wait at least %3$s seconds before attempting to post again.'), $SpamCount, $SpamTime, $SpamLock)); // Update the 'waiting period' every time they try to post again $Attributes['Date' . $Type . 'SpamCheck'] = Gdn_Format::ToDateTime(); } else { if ($SecondsSinceSpamCheck > $SpamTime) { $Attributes['Count' . $Type . 'SpamCheck'] = 1; $Attributes['Date' . $Type . 'SpamCheck'] = Gdn_Format::ToDateTime(); } else { $Attributes['Count' . $Type . 'SpamCheck'] = $CountSpamCheck + 1; } } // Update the user profile after every comment $UserModel = Gdn::UserModel(); if ($Session->UserID) { $UserModel->SaveAttribute($Session->UserID, $Attributes); } return $Spam; }