/**
  * ToggleFollow toggles the hidden/unhidden state of categories
  *
  * it has been adopted from function Follow in
  * /applications/vanilla/controllers/class.categorycontroller.php
  * Redirection had to be fixed
  */
 public function CategoryController_ToggleFollow_Create($CategoryID, $Value, $TKey, $Target)
 {
     if (Gdn::Session()->ValidateTransientKey($TKey)) {
         $CategoryModel = new CategoryModel();
         $CategoryModel->SaveUserTree($CategoryID, array('Unfollow' => !(bool) $Value));
         if (!(bool) $Value) {
             // switch to "view only followed" when hiding a category
             $this->CategoriesController_SetToggle_Create(1, $Target);
         } else {
             // and to "view all" when no category is hidden
             $NoFollowing = TRUE;
             $Categories = $CategoryModel::Categories();
             foreach ($Categories as $Category) {
                 if ($Category['Following'] == '') {
                     $NoFollowing = FALSE;
                     break;
                 }
             }
             if ($NoFollowing) {
                 $this->CategoriesController_SetToggle_Create(0, $Target);
             }
         }
     }
     Redirect($Target);
 }
 /**
  * Record the user's watch data.
  *
  * @since 2.0.0
  * @access public
  *
  * @param object $Discussion Discussion being watched.
  * @param int $Limit Max number to get.
  * @param int $Offset Number to skip.
  * @param int $TotalComments Total in entire discussion (hard limit).
  */
 public function setWatch($Discussion, $Limit, $Offset, $TotalComments)
 {
     $NewComments = false;
     $Session = Gdn::session();
     if ($Session->UserID > 0) {
         // Max comments we could have seen
         $CountWatch = $Limit + $Offset;
         if ($CountWatch > $TotalComments) {
             $CountWatch = $TotalComments;
         }
         // This dicussion looks familiar...
         if (is_numeric($Discussion->CountCommentWatch)) {
             if ($CountWatch < $Discussion->CountCommentWatch) {
                 $CountWatch = $Discussion->CountCommentWatch;
             }
             if (isset($Discussion->DateLastViewed)) {
                 $NewComments |= Gdn_Format::toTimestamp($Discussion->DateLastComment) > Gdn_Format::toTimestamp($Discussion->DateLastViewed);
             }
             if ($TotalComments > $Discussion->CountCommentWatch) {
                 $NewComments |= true;
             }
             // Update the watch data.
             if ($NewComments) {
                 // 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 = c('Vanilla.Archive.Date', false);
             if (!$ArchiveDate || Gdn_Format::toTimestamp($Discussion->DateLastComment) > Gdn_Format::toTimestamp($ArchiveDate)) {
                 $NewComments = true;
                 // Insert watch data.
                 $this->SQL->Options('Ignore', true);
                 $this->SQL->insert('UserDiscussion', array('UserID' => $Session->UserID, 'DiscussionID' => $Discussion->DiscussionID, 'CountComments' => $CountWatch, 'DateLastViewed' => Gdn_Format::toDateTime()));
             }
         }
         /**
          * Fuzzy way of trying to automatically mark a cateogyr read again
          * if the user reads all the comments on the first few pages.
          */
         // If this discussion is in a category that has been marked read,
         // check if reading this thread causes it to be completely read again
         $CategoryID = val('CategoryID', $Discussion);
         if ($CategoryID) {
             $Category = CategoryModel::categories($CategoryID);
             if ($Category) {
                 $DateMarkedRead = val('DateMarkedRead', $Category);
                 if ($DateMarkedRead) {
                     // Fuzzy way of looking back about 2 pages into the past
                     $LookBackCount = c('Vanilla.Discussions.PerPage', 50) * 2;
                     // Find all discussions with content from after DateMarkedRead
                     $DiscussionModel = new DiscussionModel();
                     $Discussions = $DiscussionModel->get(0, 101, array('CategoryID' => $CategoryID, 'DateLastComment>' => $DateMarkedRead));
                     unset($DiscussionModel);
                     // Abort if we get back as many as we asked for, meaning a
                     // lot has happened.
                     $NumDiscussions = $Discussions->numRows();
                     if ($NumDiscussions <= $LookBackCount) {
                         // Loop over these and see if any are still unread
                         $MarkAsRead = true;
                         while ($Discussion = $Discussions->NextRow(DATASET_TYPE_ARRAY)) {
                             if ($Discussion['Read']) {
                                 continue;
                             }
                             $MarkAsRead = false;
                             break;
                         }
                         // Mark this category read if all the new content is read
                         if ($MarkAsRead) {
                             $CategoryModel = new CategoryModel();
                             $CategoryModel->SaveUserTree($CategoryID, array('DateMarkedRead' => Gdn_Format::toDateTime()));
                             unset($CategoryModel);
                         }
                     }
                 }
             }
         }
     }
 }