/** * Insert or update meta data about the comment. * * Updates unread comment totals, bookmarks, and activity. Sends notifications. * * @since 2.0.0 * @access public * * @param array $CommentID Unique ID for this comment. * @param int $Insert Used as a boolean for whether this is a new comment. * @param bool $CheckExisting Not used. * @param bool $IncUser Whether or not to just increment the user's comment count rather than recalculate it. */ public function save2($CommentID, $Insert, $CheckExisting = true, $IncUser = false) { $Session = Gdn::session(); $UserModel = Gdn::userModel(); // Load comment data $Fields = $this->getID($CommentID, DATASET_TYPE_ARRAY); // Clear any session stashes related to this discussion $DiscussionModel = new DiscussionModel(); $DiscussionID = val('DiscussionID', $Fields); $Discussion = $DiscussionModel->getID($DiscussionID); $Session->Stash('CommentForForeignID_' . GetValue('ForeignID', $Discussion)); // Make a quick check so that only the user making the comment can make the notification. // This check may be used in the future so should not be depended on later in the method. if (Gdn::controller()->deliveryType() === DELIVERY_TYPE_ALL && $Fields['InsertUserID'] != $Session->UserID) { return; } // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. $this->UpdateUser($Fields['InsertUserID'], $IncUser && $Insert); // Mark the user as participated. $this->SQL->replace('UserDiscussion', array('Participated' => 1), array('DiscussionID' => $DiscussionID, 'UserID' => val('InsertUserID', $Fields))); if ($Insert) { // UPDATE COUNT AND LAST COMMENT ON CATEGORY TABLE if ($Discussion->CategoryID > 0) { $Category = CategoryModel::categories($Discussion->CategoryID); if ($Category) { $CountComments = val('CountComments', $Category, 0) + 1; if ($CountComments < self::COMMENT_THRESHOLD_SMALL || $CountComments < self::COMMENT_THRESHOLD_LARGE && $CountComments % self::COUNT_RECALC_MOD == 0) { $CountComments = $this->SQL->select('CountComments', 'sum', 'CountComments')->from('Discussion')->where('CategoryID', $Discussion->CategoryID)->get()->firstRow()->CountComments; } } $CategoryModel = new CategoryModel(); $CategoryModel->setField($Discussion->CategoryID, array('LastDiscussionID' => $DiscussionID, 'LastCommentID' => $CommentID, 'CountComments' => $CountComments, 'LastDateInserted' => $Fields['DateInserted'])); // Update the cache. $CategoryCache = array('LastTitle' => $Discussion->Name, 'LastUserID' => $Fields['InsertUserID'], 'LastUrl' => DiscussionUrl($Discussion) . '#latest'); CategoryModel::SetCache($Discussion->CategoryID, $CategoryCache); } // Prepare the notification queue. $ActivityModel = new ActivityModel(); $HeadlineFormat = t('HeadlineFormat.Comment', '{ActivityUserID,user} commented on <a href="{Url,html}">{Data.Name,text}</a>'); $Category = CategoryModel::categories($Discussion->CategoryID); $Activity = array('ActivityType' => 'Comment', 'ActivityUserID' => $Fields['InsertUserID'], 'HeadlineFormat' => $HeadlineFormat, 'RecordType' => 'Comment', 'RecordID' => $CommentID, 'Route' => "/discussion/comment/{$CommentID}#Comment_{$CommentID}", 'Data' => array('Name' => $Discussion->Name, 'Category' => val('Name', $Category))); // Allow simple fulltext notifications if (c('Vanilla.Activity.ShowCommentBody', false)) { $Activity['Story'] = val('Body', $Fields); $Activity['Format'] = val('Format', $Fields); } // Pass generic activity to events. $this->EventArguments['Activity'] = $Activity; // Notify users who have bookmarked the discussion. $BookmarkData = $DiscussionModel->GetBookmarkUsers($DiscussionID); foreach ($BookmarkData->result() as $Bookmark) { // Check user can still see the discussion. if (!$UserModel->GetCategoryViewPermission($Bookmark->UserID, $Discussion->CategoryID)) { continue; } $Activity['NotifyUserID'] = $Bookmark->UserID; $Activity['Data']['Reason'] = 'bookmark'; $ActivityModel->Queue($Activity, 'BookmarkComment', array('CheckRecord' => true)); } // Notify users who have participated in the discussion. $ParticipatedData = $DiscussionModel->GetParticipatedUsers($DiscussionID); foreach ($ParticipatedData->result() as $UserRow) { if (!$UserModel->GetCategoryViewPermission($UserRow->UserID, $Discussion->CategoryID)) { continue; } $Activity['NotifyUserID'] = $UserRow->UserID; $Activity['Data']['Reason'] = 'participated'; $ActivityModel->Queue($Activity, 'ParticipateComment', array('CheckRecord' => true)); } // Record user-comment activity. if ($Discussion != false) { $InsertUserID = val('InsertUserID', $Discussion); // Check user can still see the discussion. if ($UserModel->GetCategoryViewPermission($InsertUserID, $Discussion->CategoryID)) { $Activity['NotifyUserID'] = $InsertUserID; $Activity['Data']['Reason'] = 'mine'; $ActivityModel->Queue($Activity, 'DiscussionComment'); } } // Record advanced notifications. if ($Discussion !== false) { $Activity['Data']['Reason'] = 'advanced'; $this->RecordAdvancedNotications($ActivityModel, $Activity, $Discussion); } // Notify any users who were mentioned in the comment. $Usernames = GetMentions($Fields['Body']); foreach ($Usernames as $i => $Username) { $User = $UserModel->GetByUsername($Username); if (!$User) { unset($Usernames[$i]); continue; } // Check user can still see the discussion. if (!$UserModel->GetCategoryViewPermission($User->UserID, $Discussion->CategoryID)) { continue; } $HeadlineFormatBak = $Activity['HeadlineFormat']; $Activity['HeadlineFormat'] = t('HeadlineFormat.Mention', '{ActivityUserID,user} mentioned you in <a href="{Url,html}">{Data.Name,text}</a>'); $Activity['NotifyUserID'] = $User->UserID; $Activity['Data']['Reason'] = 'mention'; $ActivityModel->Queue($Activity, 'Mention'); $Activity['HeadlineFormat'] = $HeadlineFormatBak; } unset($Activity['Data']['Reason']); // Throw an event for users to add their own events. $this->EventArguments['Comment'] = $Fields; $this->EventArguments['Discussion'] = $Discussion; $this->EventArguments['NotifiedUsers'] = array_keys(ActivityModel::$Queue); $this->EventArguments['MentionedUsers'] = $Usernames; $this->EventArguments['ActivityModel'] = $ActivityModel; $this->fireEvent('BeforeNotification'); // Send all notifications. $ActivityModel->SaveQueue(); } }
public function Save2($CommentID, $Insert, $CheckExisting = TRUE) { $Fields = $this->GetID($CommentID, DATASET_TYPE_ARRAY); $Session = Gdn::Session(); // Make a quick check so that only the user making the comment can make the notification. // This check may be used in the future so should not be depended on later in the method. if ($Fields['InsertUserID'] != $Session->UserID) { return; } $DiscussionModel = new DiscussionModel(); $DiscussionID = ArrayValue('DiscussionID', $Fields); $Discussion = $DiscussionModel->GetID($DiscussionID); if ($Insert) { // Notify any users who were mentioned in the comment $Usernames = GetMentions($Fields['Body']); $UserModel = Gdn::UserModel(); $Story = ArrayValue('Body', $Fields, ''); $NotifiedUsers = array(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { $NotifiedUsers[] = $User->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'CommentMention', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $User->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } // Notify users who have bookmarked the discussion $BookmarkData = $DiscussionModel->GetBookmarkUsers($DiscussionID); foreach ($BookmarkData->Result() as $Bookmark) { if (!in_array($Bookmark->UserID, $NotifiedUsers) && $Bookmark->UserID != $Session->UserID) { $NotifiedUsers[] = $Bookmark->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'BookmarkComment', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $Bookmark->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } // Record user-comment activity if ($Discussion !== FALSE && !in_array($Session->UserID, $NotifiedUsers)) { $this->RecordActivity($Discussion, $Session->UserID, $CommentID, 'Only'); } } $this->UpdateCommentCount($DiscussionID); // Mark the comment read (note: add 1 to $Discussion->CountComments because this comment has been added since $Discussion was loaded) $this->SetWatch($Discussion, $Discussion->CountComments, $Discussion->CountComments + 1, $Discussion->CountComments + 1); // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. $Data = $this->SQL->Select('d.InsertUserID')->Select('d.DiscussionID', 'count', 'CountDiscussions')->From('Discussion d')->Join('Comment c', 'd.DiscussionID = c.DiscussionID')->Join('UserDiscussion w', 'd.DiscussionID = w.DiscussionID and w.UserID = d.InsertUserID')->Where('w.CountComments >', 0)->Where('c.InsertUserID', $Session->UserID)->Where('c.InsertUserID <>', 'd.InsertUserID', TRUE, FALSE)->GroupBy('d.InsertUserID')->Get(); if ($Data->NumRows() > 0) { $UserData = $Data->FirstRow(); $this->SQL->Update('User')->Set('CountUnreadDiscussions', $UserData->CountDiscussions)->Where('UserID', $UserData->InsertUserID)->Put(); } $this->UpdateUser($Session->UserID); }
/** * Insert or update meta data about the comment. * * Updates unread comment totals, bookmarks, and activity. Sends notifications. * * @since 2.0.0 * @access public * * @param array $CommentID Unique ID for this comment. * @param int $Insert Used as a boolean for whether this is a new comment. * @param bool $CheckExisting Not used. * @param bool $IncUser Whether or not to just increment the user's comment count rather than recalculate it. */ public function Save2($CommentID, $Insert, $CheckExisting = TRUE, $IncUser = FALSE) { $Session = Gdn::Session(); // Load comment data $Fields = $this->GetID($CommentID, DATASET_TYPE_ARRAY); // Clear any session stashes related to this discussion $Session->Stash('CommentForDiscussionID_' . GetValue('DiscussionID', $Fields)); // Make a quick check so that only the user making the comment can make the notification. // This check may be used in the future so should not be depended on later in the method. if ($Fields['InsertUserID'] != $Session->UserID) { return; } // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. // $Data = $this->SQL // ->Select('d.InsertUserID') // ->Select('d.DiscussionID', 'count', 'CountDiscussions') // ->From('Discussion d') // ->Join('Comment c', 'd.DiscussionID = c.DiscussionID') // ->Join('UserDiscussion w', 'd.DiscussionID = w.DiscussionID and w.UserID = d.InsertUserID') // ->Where('w.CountComments >', 0) // ->Where('c.InsertUserID', $Session->UserID) // ->Where('c.InsertUserID <>', 'd.InsertUserID', TRUE, FALSE) // ->GroupBy('d.InsertUserID') // ->Get(); // // if ($Data->NumRows() > 0) { // $UserData = $Data->FirstRow(); // $this->SQL // ->Update('User') // ->Set('CountUnreadDiscussions', $UserData->CountDiscussions) // ->Where('UserID', $UserData->InsertUserID) // ->Put(); // } $this->UpdateUser($Session->UserID, $IncUser && $Insert); if ($Insert) { $DiscussionModel = new DiscussionModel(); $DiscussionID = GetValue('DiscussionID', $Fields); $Discussion = $DiscussionModel->GetID($DiscussionID); // UPDATE COUNT AND LAST COMMENT ON CATEGORY TABLE if ($Discussion->CategoryID > 0) { $CountComments = $this->SQL->Select('CountComments', 'sum', 'CountComments')->From('Discussion')->Where('CategoryID', $Discussion->CategoryID)->Get()->FirstRow()->CountComments; $CategoryModel = new CategoryModel(); $CategoryModel->SetField($Discussion->CategoryID, array('LastDiscussionID' => $Discussion->DiscussionID, 'LastCommentID' => $Discussion->LastCommentID, 'CountComments' => $CountComments)); // Update the cache. if ($DiscussionID && Gdn::Cache()->ActiveEnabled()) { $CategoryCache = array('LastDiscussionID' => $DiscussionID, 'LastCommentID' => $CommentID, 'LastTitle' => $Discussion->Name, 'LastUserID' => $Fields['InsertUserID'], 'LastDateInserted' => $Fields['DateInserted'], 'LastUrl' => "/discussion/comment/{$CommentID}#Comment_{$CommentID}"); CategoryModel::SetCache($Discussion->CategoryID, $CategoryCache); } } // Prepare the notification queue. $ActivityModel = new ActivityModel(); $ActivityModel->ClearNotificationQueue(); // Notify any users who were mentioned in the comment. $Usernames = GetMentions($Fields['Body']); $UserModel = Gdn::UserModel(); $Story = '[' . $Discussion->Name . "]\n" . ArrayValue('Body', $Fields, ''); $NotifiedUsers = array(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); // Check user can still see the discussion. $UserMayView = $UserModel->GetCategoryViewPermission($User->UserID, $Discussion->CategoryID); if ($User && $User->UserID != $Session->UserID && $UserMayView) { $NotifiedUsers[] = $User->UserID; $ActivityID = $ActivityModel->Add($Session->UserID, 'CommentMention', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $User->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->QueueNotification($ActivityID, $Story); } } // Notify users who have bookmarked the discussion. $BookmarkData = $DiscussionModel->GetBookmarkUsers($DiscussionID); foreach ($BookmarkData->Result() as $Bookmark) { if (in_array($Bookmark->UserID, $NotifiedUsers) || $Bookmark->UserID == $Session->UserID) { continue; } // Check user can still see the discussion. $UserMayView = $UserModel->GetCategoryViewPermission($Bookmark->UserID, $Discussion->CategoryID); if ($UserMayView) { $NotifiedUsers[] = $Bookmark->UserID; // $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'BookmarkComment', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $Bookmark->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->QueueNotification($ActivityID, $Story); } } // Record user-comment activity. if ($Discussion !== FALSE && !in_array($Session->UserID, $NotifiedUsers)) { $ActivityID = $this->RecordActivity($ActivityModel, $Discussion, $Session->UserID, $CommentID, FALSE); if ($ActivityID) { $ActivityModel->QueueNotification($ActivityID, $Story); $NotifiedUsers[] = $Session->UserID; } } // Record advanced notifications. if ($Discussion !== FALSE) { $this->RecordAdvancedNotications($ActivityModel, $Discussion, $Fields, $NotifiedUsers); } // Throw an event for users to add their own events. $this->EventArguments['Comment'] = $Fields; $this->EventArguments['Discussion'] = $Discussion; $this->EventArguments['NotifiedUsers'] = $NotifiedUsers; $this->EventArguments['ActivityModel'] = $ActivityModel; $this->FireEvent('BeforeNotification'); // Send all notifications. $ActivityModel->SendNotificationQueue(); } }
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; }
/** * Inserts or updates the discussion via form values. * * Events: BeforeSaveDiscussion, AfterSaveDiscussion. * * @since 2.0.0 * @access public * * @param array $FormPostValues Data sent from the form model. * @return int $DiscussionID Unique ID of the discussion. */ 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->Validation->AddRule('MeAction', 'function:ValidateMeAction'); $this->Validation->ApplyRule('Body', 'MeAction'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } // Validate category permissions. $CategoryID = GetValue('CategoryID', $FormPostValues); if ($CategoryID > 0) { $Category = CategoryModel::Categories($CategoryID); if ($Category && !$Session->CheckPermission('Vanilla.Discussions.Add', TRUE, 'Category', GetValue('PermissionCategoryID', $Category))) { $this->Validation->AddValidationResult('CategoryID', 'You do not have permission to post in this category'); } } // Get the DiscussionID from the form so we know if we are inserting or updating. $DiscussionID = ArrayValue('DiscussionID', $FormPostValues, ''); // See if there is a source ID. if (GetValue('SourceID', $FormPostValues)) { $DiscussionID = $this->SQL->GetWhere('Discussion', ArrayTranslate($FormPostValues, array('Source', 'SourceID')))->Value('DiscussionID'); if ($DiscussionID) { $FormPostValues['DiscussionID'] = $DiscussionID; } } elseif (GetValue('ForeignID', $FormPostValues)) { $DiscussionID = $this->SQL->GetWhere('Discussion', array('ForeignID' => $FormPostValues['ForeignID']))->Value('DiscussionID'); if ($DiscussionID) { $FormPostValues['DiscussionID'] = $DiscussionID; } } $Insert = $DiscussionID == '' ? TRUE : FALSE; $this->EventArguments['Insert'] = $Insert; if ($Insert) { unset($FormPostValues['DiscussionID']); // If no categoryid is defined, grab the first available. if (!GetValue('CategoryID', $FormPostValues) && !C('Vanilla.Categories.Use')) { $FormPostValues['CategoryID'] = GetValue('CategoryID', CategoryModel::DefaultCategory(), -1); } $this->AddInsertFields($FormPostValues); // The UpdateUserID used to be required. Just add it if it still is. if (!$this->Schema->GetProperty('UpdateUserID', 'AllowNull', TRUE)) { $FormPostValues['UpdateUserID'] = $FormPostValues['InsertUserID']; } // $FormPostValues['LastCommentUserID'] = $Session->UserID; $FormPostValues['DateLastComment'] = $FormPostValues['DateInserted']; } else { // Add the update fields. $this->AddUpdateFields($FormPostValues); } // Set checkbox values to zero if they were unchecked if (ArrayValue('Announce', $FormPostValues, '') === FALSE) { $FormPostValues['Announce'] = 0; } if (ArrayValue('Closed', $FormPostValues, '') === FALSE) { $FormPostValues['Closed'] = 0; } if (ArrayValue('Sink', $FormPostValues, '') === FALSE) { $FormPostValues['Sink'] = 0; } // Prep and fire event $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('BeforeSaveDiscussion'); // Validate the form posted values $this->Validate($FormPostValues, $Insert); $ValidationResults = $this->ValidationResults(); // If the body is not required, remove it's validation errors. $BodyRequired = C('Vanilla.DiscussionBody.Required', TRUE); if (!$BodyRequired && array_key_exists('Body', $ValidationResults)) { unset($ValidationResults['Body']); } if (count($ValidationResults) == 0) { // If the post is new and it validates, make sure the user isn't spamming if (!$Insert || !$this->CheckForSpam('Discussion')) { // Get all fields on the form that relate to the schema $Fields = $this->Validation->SchemaValidationFields(); // Get DiscussionID if one was sent $DiscussionID = intval(ArrayValue('DiscussionID', $Fields, 0)); // Remove the primary key from the fields for saving $Fields = RemoveKeyFromArray($Fields, 'DiscussionID'); $StoredCategoryID = FALSE; if ($DiscussionID > 0) { // Updating $Stored = $this->GetID($DiscussionID, DATASET_TYPE_ARRAY); // Clear the cache if necessary. if (GetValue('Announce', $Stored) != GetValue('Announce', $Fields)) { $CacheKeys = array('Announcements'); $this->SQL->Cache($CacheKeys); } self::SerializeRow($Fields); $this->SQL->Put($this->Name, $Fields, array($this->PrimaryKey => $DiscussionID)); SetValue('DiscussionID', $Fields, $DiscussionID); LogModel::LogChange('Edit', 'Discussion', (array) $Fields, $Stored); if (GetValue('CategoryID', $Stored) != GetValue('CategoryID', $Fields)) { $StoredCategoryID = GetValue('CategoryID', $Stored); } } else { // Inserting. if (!GetValue('Format', $Fields) || C('Garden.ForceInputFormatter')) { $Fields['Format'] = C('Garden.InputFormatter', ''); } if (C('Vanilla.QueueNotifications')) { $Fields['Notified'] = ActivityModel::SENT_PENDING; } // Check for spam. $Spam = SpamModel::IsSpam('Discussion', $Fields); if ($Spam) { return SPAM; } // Check for approval $ApprovalRequired = CheckRestriction('Vanilla.Approval.Require'); if ($ApprovalRequired && !GetValue('Verified', Gdn::Session()->User)) { LogModel::Insert('Pending', 'Discussion', $Fields); return UNAPPROVED; } // Create discussion $DiscussionID = $this->SQL->Insert($this->Name, $Fields); $Fields['DiscussionID'] = $DiscussionID; // Update the cache. if ($DiscussionID && Gdn::Cache()->ActiveEnabled()) { $CategoryCache = array('LastDiscussionID' => $DiscussionID, 'LastCommentID' => NULL, 'LastTitle' => Gdn_Format::Text($Fields['Name']), 'LastUserID' => $Fields['InsertUserID'], 'LastDateInserted' => $Fields['DateInserted'], 'LastUrl' => DiscussionUrl($Fields)); CategoryModel::SetCache($Fields['CategoryID'], $CategoryCache); // Clear the cache if necessary. if (GetValue('Announce', $Fields)) { Gdn::Cache()->Remove('Announcements'); } } // Update the user's discussion count. $this->UpdateUserDiscussionCount(Gdn::Session()->UserID); // Assign the new DiscussionID to the comment before saving. $FormPostValues['IsNewDiscussion'] = TRUE; $FormPostValues['DiscussionID'] = $DiscussionID; // Do data prep. $DiscussionName = ArrayValue('Name', $Fields, ''); $Story = ArrayValue('Body', $Fields, ''); $NotifiedUsers = array(); $UserModel = Gdn::UserModel(); $ActivityModel = new ActivityModel(); if (GetValue('Type', $FormPostValues)) { $Code = 'HeadlineFormat.Discussion.' . $FormPostValues['Type']; } else { $Code = 'HeadlineFormat.Discussion'; } $HeadlineFormat = T($Code, '{ActivityUserID,user} started a new discussion: <a href="{Url,html}">{Data.Name,text}</a>'); $Category = CategoryModel::Categories(GetValue('CategoryID', $Fields)); $Activity = array('ActivityType' => 'Discussion', 'ActivityUserID' => $Fields['InsertUserID'], 'HeadlineFormat' => $HeadlineFormat, 'RecordType' => 'Discussion', 'RecordID' => $DiscussionID, 'Route' => DiscussionUrl($Fields), 'Data' => array('Name' => $DiscussionName, 'Category' => GetValue('Name', $Category))); // Allow simple fulltext notifications if (C('Vanilla.Activity.ShowDiscussionBody', FALSE)) { $Activity['Story'] = $Story; } // Notify all of the users that were mentioned in the discussion. $Usernames = array_merge(GetMentions($DiscussionName), GetMentions($Story)); $Usernames = array_unique($Usernames); // Use our generic Activity for events, not mentions $this->EventArguments['Activity'] = $Activity; // Notifications for mentions foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if (!$User) { continue; } // Check user can still see the discussion. if (!$UserModel->GetCategoryViewPermission($User->UserID, GetValue('CategoryID', $Fields))) { continue; } $Activity['HeadlineFormat'] = T('HeadlineFormat.Mention', '{ActivityUserID,user} mentioned you in <a href="{Url,html}">{Data.Name,text}</a>'); $Activity['NotifyUserID'] = GetValue('UserID', $User); $ActivityModel->Queue($Activity, 'Mention'); } // Notify everyone that has advanced notifications. if (!C('Vanilla.QueueNotifications')) { try { $Fields['DiscussionID'] = $DiscussionID; $this->NotifyNewDiscussion($Fields, $ActivityModel, $Activity); } catch (Exception $Ex) { throw $Ex; } } // Throw an event for users to add their own events. $this->EventArguments['Discussion'] = $Fields; $this->EventArguments['NotifiedUsers'] = $NotifiedUsers; $this->EventArguments['MentionedUsers'] = $Usernames; $this->EventArguments['ActivityModel'] = $ActivityModel; $this->FireEvent('BeforeNotification'); // Send all notifications. $ActivityModel->SaveQueue(); } // Get CategoryID of this discussion $Discussion = $this->GetID($DiscussionID, DATASET_TYPE_ARRAY); $CategoryID = GetValue('CategoryID', $Discussion, FALSE); // Update discussion counter for affected categories $this->UpdateDiscussionCount($CategoryID, $Insert ? $Discussion : FALSE); if ($StoredCategoryID) { $this->UpdateDiscussionCount($StoredCategoryID); } // Fire an event that the discussion was saved. $this->EventArguments['FormPostValues'] = $FormPostValues; $this->EventArguments['Fields'] = $Fields; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('AfterSaveDiscussion'); } } return $DiscussionID; }
/** * Insert or update meta data about the comment. * * Updates unread comment totals, bookmarks, and activity. Sends notifications. * * @since 2.0.0 * @access public * * @param array $CommentID Unique ID for this comment. * @param int $Insert Used as a boolean for whether this is a new comment. * @param bool $CheckExisting Not used. * @param bool $IncUser Whether or not to just increment the user's comment count rather than recalculate it. */ public function Save2($CommentID, $Insert, $CheckExisting = TRUE, $IncUser = FALSE) { $Session = Gdn::Session(); $UserModel = Gdn::UserModel(); // Load comment data $Fields = $this->GetID($CommentID, DATASET_TYPE_ARRAY); // Clear any session stashes related to this discussion $DiscussionModel = new DiscussionModel(); $DiscussionID = GetValue('DiscussionID', $Fields); $Discussion = $DiscussionModel->GetID($DiscussionID); $Session->Stash('CommentForForeignID_' . GetValue('ForeignID', $Discussion)); // Make a quick check so that only the user making the comment can make the notification. // This check may be used in the future so should not be depended on later in the method. if ($Fields['InsertUserID'] != $Session->UserID) { return; } // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. $this->UpdateUser($Session->UserID, $IncUser && $Insert); if ($Insert) { // UPDATE COUNT AND LAST COMMENT ON CATEGORY TABLE if ($Discussion->CategoryID > 0) { $CountComments = $this->SQL->Select('CountComments', 'sum', 'CountComments')->From('Discussion')->Where('CategoryID', $Discussion->CategoryID)->Get()->FirstRow()->CountComments; $CategoryModel = new CategoryModel(); $CategoryModel->SetField($Discussion->CategoryID, array('LastDiscussionID' => $DiscussionID, 'LastCommentID' => $CommentID, 'CountComments' => $CountComments, 'LastDateInserted' => $Fields['DateInserted'])); // Update the cache. if ($DiscussionID && Gdn::Cache()->ActiveEnabled()) { $CategoryCache = array('LastTitle' => $Discussion->Name, 'LastUserID' => $Fields['InsertUserID'], 'LastUrl' => DiscussionUrl($Discussion) . '#latest'); CategoryModel::SetCache($Discussion->CategoryID, $CategoryCache); } } // Prepare the notification queue. $ActivityModel = new ActivityModel(); $HeadlineFormat = T('HeadlineFormat.Comment', '{ActivityUserID,user} commented on <a href="{Url,html}">{Data.Name,text}</a>'); $Category = CategoryModel::Categories($Discussion->CategoryID); $Activity = array('ActivityType' => 'Comment', 'ActivityUserID' => $Fields['InsertUserID'], 'HeadlineFormat' => $HeadlineFormat, 'RecordType' => 'Comment', 'RecordID' => $CommentID, 'Route' => "/discussion/comment/{$CommentID}#Comment_{$CommentID}", 'Data' => array('Name' => $Discussion->Name, 'Category' => GetValue('Name', $Category))); // Allow simple fulltext notifications if (C('Vanilla.Activity.ShowCommentBody', FALSE)) { $Activity['Story'] = GetValue('Body', $Fields); } // Notify users who have bookmarked the discussion. $BookmarkData = $DiscussionModel->GetBookmarkUsers($DiscussionID); foreach ($BookmarkData->Result() as $Bookmark) { // Check user can still see the discussion. if (!$UserModel->GetCategoryViewPermission($Bookmark->UserID, $Discussion->CategoryID)) { continue; } $Activity['NotifyUserID'] = $Bookmark->UserID; $ActivityModel->Queue($Activity, 'BookmarkComment', array('CheckRecord' => TRUE)); } // Record user-comment activity. if ($Discussion != FALSE) { $Activity['NotifyUserID'] = GetValue('InsertUserID', $Discussion); $ActivityModel->Queue($Activity, 'DiscussionComment'); } // Record advanced notifications. if ($Discussion !== FALSE) { $this->RecordAdvancedNotications($ActivityModel, $Activity, $Discussion); } // Notify any users who were mentioned in the comment. $Usernames = GetMentions($Fields['Body']); $NotifiedUsers = array(); foreach ($Usernames as $i => $Username) { $User = $UserModel->GetByUsername($Username); if (!$User) { unset($Usernames[$i]); continue; } // Check user can still see the discussion. if (!$UserModel->GetCategoryViewPermission($User->UserID, $Discussion->CategoryID)) { continue; } $HeadlineFormatBak = $Activity['HeadlineFormat']; $Activity['HeadlineFormat'] = T('HeadlineFormat.Mention', '{ActivityUserID,user} mentioned you in <a href="{Url,html}">{Data.Name,text}</a>'); $Activity['NotifyUserID'] = $User->UserID; $ActivityModel->Queue($Activity, 'Mention'); $Activity['HeadlineFormat'] = $HeadlineFormatBak; } // Throw an event for users to add their own events. $this->EventArguments['Comment'] = $Fields; $this->EventArguments['Discussion'] = $Discussion; $this->EventArguments['NotifiedUsers'] = array_keys(ActivityModel::$Queue); $this->EventArguments['MentionedUsers'] = $Usernames; $this->EventArguments['ActivityModel'] = $ActivityModel; $this->FireEvent('BeforeNotification'); // Send all notifications. $ActivityModel->SaveQueue(); } }
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'); } $CommentID = ArrayValue('CommentID', $FormPostValues); $CommentID = is_numeric($CommentID) && $CommentID > 0 ? $CommentID : FALSE; $Insert = $CommentID === FALSE; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, check for spam if (!$Insert || !$this->CheckForSpam('Comment')) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); $DiscussionModel = new Gdn_DiscussionModel(); $DiscussionID = ArrayValue('DiscussionID', $Fields); $Discussion = $DiscussionModel->GetID($DiscussionID); $DiscussionAuthorMentioned = FALSE; if ($Insert === FALSE) { $this->SQL->Put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { // Make sure that the comments get formatted in the method defined by Garden $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); $CommentID = $this->SQL->Insert($this->Name, $Fields); $this->EventArguments['CommentID'] = $CommentID; $this->FireEvent('SaveCommentAfter'); // Notify any users who were mentioned in the comment $Usernames = GetMentions($Fields['Body']); $UserModel = Gdn::UserModel(); $DiscussionName = ''; foreach ($Usernames as $Username) { $User = $UserModel->GetWhere(array('Name' => $Username))->FirstRow(); if ($User && $User->UserID != $Session->UserID) { if ($User->UserID == $Discussion->InsertUserID) { $DiscussionAuthorMentioned = TRUE; } AddActivity($Session->UserID, 'CommentMention', Anchor(Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $User->UserID, 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID); } } } // Record user-comment activity if ($Insert === TRUE && $Discussion !== FALSE && $DiscussionAuthorMentioned === FALSE) { $this->RecordActivity($Discussion, $Session->UserID, $CommentID); } // Only record activity if inserting a comment, not on edit. $this->UpdateCommentCount($DiscussionID); // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. $Data = $this->SQL->Select('d.InsertUserID')->Select('d.DiscussionID', 'count', 'CountDiscussions')->From('Discussion d')->Join('Comment c', 'd.DiscussionID = c.DiscussionID')->Join('UserDiscussion w', 'd.DiscussionID = w.DiscussionID and w.UserID = d.InsertUserID')->Where('w.CountComments >', 0)->Where('c.InsertUserID', $Session->UserID)->Where('c.InsertUserID <>', 'd.InsertUserID', TRUE, FALSE)->GroupBy('d.InsertUserID')->Get(); if ($Data->NumRows() > 0) { $UserData = $Data->FirstRow(); $this->SQL->Update('User')->Set('CountUnreadDiscussions', $UserData->CountDiscussions)->Where('UserID', $UserData->InsertUserID)->Put(); } // Index the post. $Search = Gdn::Factory('SearchModel'); if (!is_null($Search)) { if (array_key_exists('Name', $FormPostValues) && array_key_exists('CategoryID', $FormPostValues)) { $Title = $FormPostValues['Name']; $CategoryID = $FormPostValues['CategoryID']; } else { // Get the name from the discussion. $Row = $this->SQL->GetWhere('Discussion', array('DiscussionID' => $DiscussionID))->FirstRow(); if (is_object($Row)) { $Title = $Row->Name; $CategoryID = $Row->CategoryID; } } $Offset = $this->GetOffset($CommentID); // Index the discussion. $Document = array('TableName' => 'Comment', 'PrimaryID' => $CommentID, 'PermissionJunctionID' => $CategoryID, 'Title' => $Title, 'Summary' => $FormPostValues['Body'], 'Url' => '/discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, 'InsertUserID' => $Session->UserID); $Search->Index($Document, $Offset == 1 ? $Document['Title'] . ' ' . $Document['Summary'] : NULL); } $this->UpdateUser($Session->UserID); } } return $CommentID; }
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'); } $CommentID = ArrayValue('CommentID', $FormPostValues); $CommentID = is_numeric($CommentID) && $CommentID > 0 ? $CommentID : FALSE; $Insert = $CommentID === FALSE; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, check for spam if (!$Insert || !$this->CheckForSpam('Comment')) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); $DiscussionModel = new DiscussionModel(); $DiscussionID = ArrayValue('DiscussionID', $Fields); $Discussion = $DiscussionModel->GetID($DiscussionID); if ($Insert === FALSE) { $this->SQL->Put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { // Make sure that the comments get formatted in the method defined by Garden $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); $CommentID = $this->SQL->Insert($this->Name, $Fields); $this->EventArguments['CommentID'] = $CommentID; // IsNewDiscussion is passed when the first comment for new discussions are created. $this->EventArguments['IsNewDiscussion'] = ArrayValue('IsNewDiscussion', $FormPostValues); $this->FireEvent('AfterSaveComment'); // Notify any users who were mentioned in the comment $Usernames = GetMentions($Fields['Body']); $UserModel = Gdn::UserModel(); $Story = ArrayValue('Body', $Fields, ''); $NotifiedUsers = array(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { $NotifiedUsers[] = $User->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'CommentMention', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $User->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } // Notify users who have bookmarked the discussion $BookmarkData = $DiscussionModel->GetBookmarkUsers($DiscussionID); foreach ($BookmarkData->Result() as $Bookmark) { if (!in_array($Bookmark->UserID, $NotifiedUsers) && $Bookmark->UserID != $Session->UserID) { $NotifiedUsers[] = $Bookmark->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'BookmarkComment', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $Bookmark->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } } // Record user-comment activity if ($Insert === TRUE && $Discussion !== FALSE && !in_array($Session->UserID, $NotifiedUsers)) { $this->RecordActivity($Discussion, $Session->UserID, $CommentID); } $this->UpdateCommentCount($DiscussionID); // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. $Data = $this->SQL->Select('d.InsertUserID')->Select('d.DiscussionID', 'count', 'CountDiscussions')->From('Discussion d')->Join('Comment c', 'd.DiscussionID = c.DiscussionID')->Join('UserDiscussion w', 'd.DiscussionID = w.DiscussionID and w.UserID = d.InsertUserID')->Where('w.CountComments >', 0)->Where('c.InsertUserID', $Session->UserID)->Where('c.InsertUserID <>', 'd.InsertUserID', TRUE, FALSE)->GroupBy('d.InsertUserID')->Get(); if ($Data->NumRows() > 0) { $UserData = $Data->FirstRow(); $this->SQL->Update('User')->Set('CountUnreadDiscussions', $UserData->CountDiscussions)->Where('UserID', $UserData->InsertUserID)->Put(); } $this->UpdateUser($Session->UserID); } } return $CommentID; }
/** * Inserts or updates the discussion via form values. * * Events: BeforeSaveDiscussion, AfterSaveDiscussion. * * @since 2.0.0 * @access public * * @param array $FormPostValues Data sent from the form model. * @return int $DiscussionID Unique ID of the discussion. */ 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, ''); // See if there is a source ID. if (array_key_exists('SourceID', $FormPostValues)) { $DiscussionID = $this->SQL->GetWhere('Discussion', ArrayTranslate($FormPostValues, array('Source', 'SourceID')))->Value('DiscussionID'); if ($DiscussionID) { $FormPostValues['DiscussionID'] = $DiscussionID; } } $Insert = $DiscussionID == '' ? TRUE : FALSE; $this->EventArguments['Insert'] = $Insert; 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', 'CategoryID', '', 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); // Set checkbox values to zero if they were unchecked if (ArrayValue('Announce', $FormPostValues, '') === FALSE) { $FormPostValues['Announce'] = 0; } if (ArrayValue('Closed', $FormPostValues, '') === FALSE) { $FormPostValues['Closed'] = 0; } if (ArrayValue('Sink', $FormPostValues, '') === FALSE) { $FormPostValues['Sink'] = 0; } // Prep and fire event $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('BeforeSaveDiscussion'); // 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')) { // Get all fields on the form that relate to the schema $Fields = $this->Validation->SchemaValidationFields(); // Get DiscussionID if one was sent $DiscussionID = intval(ArrayValue('DiscussionID', $Fields, 0)); // Remove the primary key from the fields for saving $Fields = RemoveKeyFromArray($Fields, 'DiscussionID'); $Discussion = FALSE; $StoredCategoryID = FALSE; if ($DiscussionID > 0) { // Updating $Stored = $this->GetID($DiscussionID); // Clear the cache if necessary. if (GetValue('Announce', $Stored) != GetValue('Announce', $Fields)) { $CacheKeys = array('Announcements', 'Announcements_' . GetValue('CategoryID', $Fields)); $Announce = GetValue('Announce', $Discussion); $this->SQL->Cache($CacheKeys); } $this->SQL->Put($this->Name, $Fields, array($this->PrimaryKey => $DiscussionID)); $Fields['DiscussionID'] = $DiscussionID; LogModel::LogChange('Edit', 'Discussion', (array) $Fields, (array) $Stored); if ($Stored->CategoryID != $Fields['CategoryID']) { $StoredCategoryID = $Stored->CategoryID; } } else { // Inserting. if (!GetValue('Format', $Fields)) { $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); } // Check for spam. $Spam = SpamModel::IsSpam('Discussion', $Fields); // Clear the cache if necessary. if (GetValue('Announce', $Fields)) { $CacheKeys = array('Announcements', 'Announcements_' . GetValue('CategoryID', $Fields)); $Announce = GetValue('Announce', $Discussion); $this->SQL->Cache($CacheKeys); } if (!$Spam) { $DiscussionID = $this->SQL->Insert($this->Name, $Fields); } else { return SPAM; } // Assign the new DiscussionID to the comment before saving $FormPostValues['IsNewDiscussion'] = TRUE; $FormPostValues['DiscussionID'] = $DiscussionID; // 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)); } } // Notify any users who were mentioned in the comment $DiscussionName = ArrayValue('Name', $Fields, ''); $Story = ArrayValue('Body', $Fields, ''); $Usernames = GetMentions($Story); $NotifiedUsers = array(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { $NotifiedUsers[] = $User->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'CommentMention', Anchor(Gdn_Format::Text($DiscussionName), '/discussion/' . $DiscussionID . '/' . Gdn_Format::Url($DiscussionName), FALSE), $User->UserID, '', '/discussion/' . $DiscussionID . '/' . Gdn_Format::Url($DiscussionName), FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } $this->RecordActivity($Session->UserID, $DiscussionID, $DiscussionName); try { $Fields['DiscussionID'] = $DiscussionID; $this->NotifyNewDiscussion($Fields); } catch (Exception $Ex) { throw $Ex; } } // Get CategoryID of this discussion $Data = $this->SQL->Select('CategoryID')->From('Discussion')->Where('DiscussionID', $DiscussionID)->Get(); $CategoryID = FALSE; if ($Data->NumRows() > 0) { $CategoryID = $Data->FirstRow()->CategoryID; } // Update discussion counter for affected categories $this->UpdateDiscussionCount($CategoryID, $Insert ? $DiscussionID : FALSE); if ($StoredCategoryID) { $this->UpdateDiscussionCount($StoredCategoryID); } // Fire an event that the discussion was saved. $this->EventArguments['FormPostValues'] = $FormPostValues; $this->EventArguments['Fields'] = $Fields; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('AfterSaveDiscussion'); } } return $DiscussionID; }