protected function _SetCategoryPermissionIDs($Category, $PermissionID, $IDs) { static $CategoryModel; if (!isset($CategoryModel)) { $CategoryModel = new CategoryModel(); } $CategoryID = $Category['CategoryID']; if (isset($IDs[$CategoryID])) { $PermissionID = $CategoryID; } if ($Category['PermissionCategoryID'] != $PermissionID) { $CategoryModel->SetField($CategoryID, 'PermissionCategoryID', $PermissionID); } $ChildIDs = GetValue('ChildIDs', $Category, array()); foreach ($ChildIDs as $ChildID) { $ChildCategory = CategoryModel::Categories($ChildID); if ($ChildCategory) { $this->_SetCategoryPermissionIDs($ChildCategory, $PermissionID, $IDs); } } }
/** * 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(); } }
/** * Deleting a category photo. * * @since 2.1 * @access public * * @param int $CategoryID Unique ID of the category to have its photo deleted. */ public function DeleteCategoryPhoto($CategoryID = FALSE, $TransientKey = '') { // Check permission $this->Permission('Garden.Settings.Manage'); $RedirectUrl = 'vanilla/settings/editcategory/' . $CategoryID; if (Gdn::Session()->ValidateTransientKey($TransientKey)) { // Do removal, set message, redirect $CategoryModel = new CategoryModel(); $CategoryModel->SetField($CategoryID, 'Photo', NULL); $this->InformMessage(T('Category photo has been deleted.')); } if ($this->_DeliveryType == DELIVERY_TYPE_ALL) { Redirect($RedirectUrl); } else { $this->ControllerName = 'Home'; $this->View = 'FileNotFound'; $this->RedirectUrl = Url($RedirectUrl); $this->Render(); } }
/** * Updates the CountDiscussions value on the category based on the CategoryID * being saved. * * @since 2.0.0 * @access public * * @param int $CategoryID Unique ID of category we are updating. */ public function UpdateDiscussionCount($CategoryID, $Discussion = FALSE) { $DiscussionID = GetValue('DiscussionID', $Discussion, FALSE); if (strcasecmp($CategoryID, 'All') == 0) { $Exclude = (bool) Gdn::Config('Vanilla.Archive.Exclude'); $ArchiveDate = Gdn::Config('Vanilla.Archive.Date'); $Params = array(); $Where = ''; if ($Exclude && $ArchiveDate) { $Where = 'where d.DateLastComment > :ArchiveDate'; $Params[':ArchiveDate'] = $ArchiveDate; } // Update all categories. $Sql = "update :_Category c\n left join (\n select\n d.CategoryID,\n coalesce(count(d.DiscussionID), 0) as CountDiscussions,\n coalesce(sum(d.CountComments), 0) as CountComments\n from :_Discussion d\n {$Where}\n group by d.CategoryID\n ) d\n on c.CategoryID = d.CategoryID\n set \n c.CountDiscussions = coalesce(d.CountDiscussions, 0),\n c.CountComments = coalesce(d.CountComments, 0)"; $Sql = str_replace(':_', $this->Database->DatabasePrefix, $Sql); $this->Database->Query($Sql, $Params, 'DiscussionModel_UpdateDiscussionCount'); } elseif (is_numeric($CategoryID)) { $this->SQL->Select('d.DiscussionID', 'count', 'CountDiscussions')->Select('d.CountComments', 'sum', 'CountComments')->From('Discussion d')->Where('d.CategoryID', $CategoryID); $this->AddArchiveWhere(); $Data = $this->SQL->Get()->FirstRow(); $CountDiscussions = (int) GetValue('CountDiscussions', $Data, 0); $CountComments = (int) GetValue('CountComments', $Data, 0); $CacheAmendment = array('CountDiscussions' => $CountDiscussions, 'CountComments' => $CountComments); if ($DiscussionID) { $CacheAmendment = array_merge($CacheAmendment, array('LastDiscussionID' => $DiscussionID, 'LastCommentID' => NULL, 'LastDateInserted' => GetValue('DateInserted', $Discussion))); } $CategoryModel = new CategoryModel(); $CategoryModel->SetField($CategoryID, $CacheAmendment); $CategoryModel->SetRecentPost($CategoryID); } }
/** * 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(); } }