Example #1
0
    function writeModuleDiscussion($Discussion, $Px = 'Bookmark')
    {
        ?>
        <li id="<?php 
        echo "{$Px}_{$Discussion->DiscussionID}";
        ?>
" class="<?php 
        echo CssClass($Discussion);
        ?>
">
   <span class="Options">
      <?php 
        //      echo OptionsList($Discussion);
        echo BookmarkButton($Discussion);
        ?>
   </span>

            <div class="Title"><?php 
        echo anchor(Gdn_Format::text($Discussion->Name, false), DiscussionUrl($Discussion) . ($Discussion->CountCommentWatch > 0 ? '#Item_' . $Discussion->CountCommentWatch : ''), 'DiscussionLink');
        ?>
</div>
            <div class="Meta">
                <?php 
        $Last = new stdClass();
        $Last->UserID = $Discussion->LastUserID;
        $Last->Name = $Discussion->LastName;
        echo NewComments($Discussion);
        echo '<span class="MItem">' . Gdn_Format::date($Discussion->LastDate, 'html') . UserAnchor($Last) . '</span>';
        ?>
            </div>
        </li>
    <?php 
    }
Example #2
0
 /**
  * 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));
 }
 /**
  * Handle discussion option menu NoIndex action (simple toggle).
  */
 public function DiscussionController_NoIndex_Create($Sender, $Args)
 {
     $Sender->Permission(array('Garden.Moderation.Manage', 'Garden.Curation.Manage'), FALSE);
     // Get discussion
     $DiscussionID = $Sender->Request->Get('discussionid');
     $Discussion = $Sender->DiscussionModel->GetID($DiscussionID);
     if (!$Discussion) {
         throw NotFoundException('Discussion');
     }
     // Toggle NoIndex
     $NoIndex = GetValue('NoIndex', $Discussion) ? 0 : 1;
     // Update DateLastComment & redirect
     $Sender->DiscussionModel->SetProperty($DiscussionID, 'NoIndex', $NoIndex);
     Redirect(DiscussionUrl($Discussion));
 }
    function WriteDiscussionEvent($Discussion, $Prefix = null)
    {
        ?>
	<li class="<?php 
        echo CssClass($Discussion);
        ?>
">
		<div class="Title">
		<?php 
        echo Anchor(Gdn_Format::Text($Discussion->Name, false), DiscussionUrl($Discussion) . ($Discussion->CountCommentWatch > 0 ? '#Item_' . $Discussion->CountCommentWatch : ''), 'DiscussionLink');
        ?>
		</div><div class="Meta"><span class="MItem">
		<?php 
        echo Gdn_Format::Date($Discussion->DiscussionEventDate, 'html');
        ?>
		</span></div>
	</li>
	<?php 
    }
Example #5
0
    function writeModuleDiscussion($Discussion, $Px = 'Bookmark', $showPhotos = false)
    {
        ?>
        <li id="<?php 
        echo "{$Px}_{$Discussion->DiscussionID}";
        ?>
" class="<?php 
        echo CssClass($Discussion);
        ?>
">
            <?php 
        if ($showPhotos) {
            $firstUser = userBuilder($Discussion, 'First');
            echo userPhoto($firstUser, ['LinkClass' => 'IndexPhoto']);
        }
        ?>
   <span class="Options">
      <?php 
        //      echo OptionsList($Discussion);
        echo BookmarkButton($Discussion);
        ?>
   </span>

            <div class="Title"><?php 
        echo anchor(Gdn_Format::text($Discussion->Name, false), DiscussionUrl($Discussion) . ($Discussion->CountCommentWatch > 0 ? '#Item_' . $Discussion->CountCommentWatch : ''), 'DiscussionLink');
        ?>
</div>
            <div class="Meta DiscussionsModuleMeta">
                <?php 
        $Last = new stdClass();
        $Last->UserID = $Discussion->LastUserID;
        $Last->Name = $Discussion->LastName;
        echo NewComments($Discussion);
        $translation = pluralTranslate($Discussion->CountComments, '%s comment html', '%s comments html', t('%s comment'), t('%s comments'));
        echo '<span class="MItem">' . Gdn_Format::date($Discussion->LastDate, 'html') . UserAnchor($Last) . '</span>';
        echo '<span class="MItem CountComments Hidden">' . sprintf($translation, $Discussion->CountComments) . '</span>';
        ?>
            </div>
        </li>
    <?php 
    }
 /**
  * Handle discussion option menu Change Author action.
  */
 public function DiscussionController_Author_Create($Sender, $Args)
 {
     $DiscussionID = $Sender->Request->Get('discussionid');
     $Discussion = $Sender->DiscussionModel->GetID($DiscussionID);
     if (!$Discussion) {
         throw NotFoundException('Discussion');
     }
     // Check edit permission
     $Sender->Permission('Vanilla.Discussions.Edit', TRUE, 'Category', $Discussion->PermissionCategoryID);
     if ($Sender->Form->AuthenticatedPostBack()) {
         // Change the author
         $Name = $Sender->Form->GetFormValue('Author', '');
         $UserModel = new UserModel();
         if (trim($Name) != '') {
             $User = $UserModel->GetByUsername(trim($Name));
             if (is_object($User)) {
                 if ($Discussion->InsertUserID == $User->UserID) {
                     $Sender->Form->AddError('That user is already the discussion author.');
                 } else {
                     // Change discussion InsertUserID
                     $Sender->DiscussionModel->SetField($DiscussionID, 'InsertUserID', $User->UserID);
                     // Update users' discussion counts
                     $Sender->DiscussionModel->UpdateUserDiscussionCount($Discussion->InsertUserID);
                     $Sender->DiscussionModel->UpdateUserDiscussionCount($User->UserID, TRUE);
                     // Increment
                     // Go to the updated discussion
                     Redirect(DiscussionUrl($Discussion));
                 }
             } else {
                 $Sender->Form->AddError('No user with that name was found.');
             }
         }
     } else {
         // Form to change the author
         $Sender->SetData('Title', $Discussion->Name);
     }
     $Sender->Render('changeauthor', '', 'plugins/AuthorSelector');
 }
 /**
  *
  *
  * @param $Sender
  * @param $Args
  * @throws Gdn_UserException
  */
 public function commentModel_afterSaveComment_handler($Sender, $Args)
 {
     if (!$this->socialSharing() || !$this->accessToken()) {
         return;
     }
     $Share = valr('FormPostValues.ShareTwitter', $Args);
     if ($Share && $this->accessToken()) {
         $Row = $Args['FormPostValues'];
         $DiscussionModel = new DiscussionModel();
         $Discussion = $DiscussionModel->getID(val('DiscussionID', $Row));
         if (!$Discussion) {
             return;
         }
         $Url = DiscussionUrl($Discussion, '', true);
         $Message = SliceTwitter(Gdn_Format::plainText($Row['Body'], $Row['Format'])) . ' ' . $Url;
         $R = $this->API('/statuses/update.json', array('status' => $Message), 'POST');
     }
 }
Example #8
0
 function writePageLink($Discussion, $PageNumber)
 {
     echo anchor($PageNumber, DiscussionUrl($Discussion, $PageNumber));
 }
 /**
  * Add a method to the ModerationController to handle merging discussions.
  * @param Gdn_Controller $Sender
  */
 public function ModerationController_MergeDiscussions_Create($Sender)
 {
     $Session = Gdn::Session();
     $Sender->Form = new Gdn_Form();
     $Sender->Title(T('Merge Discussions'));
     $DiscussionModel = new DiscussionModel();
     $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array());
     if (!is_array($CheckedDiscussions)) {
         $CheckedDiscussions = array();
     }
     $DiscussionIDs = $CheckedDiscussions;
     $Sender->SetData('DiscussionIDs', $DiscussionIDs);
     $CountCheckedDiscussions = count($DiscussionIDs);
     $Sender->SetData('CountCheckedDiscussions', $CountCheckedDiscussions);
     $Discussions = $DiscussionModel->SQL->WhereIn('DiscussionID', $DiscussionIDs)->Get('Discussion')->ResultArray();
     $Sender->SetData('Discussions', $Discussions);
     // Perform the merge
     if ($Sender->Form->AuthenticatedPostBack()) {
         // Create a new discussion record
         $MergeDiscussion = FALSE;
         $MergeDiscussionID = $Sender->Form->GetFormValue('MergeDiscussionID');
         foreach ($Discussions as $Discussion) {
             if ($Discussion['DiscussionID'] == $MergeDiscussionID) {
                 $MergeDiscussion = $Discussion;
                 break;
             }
         }
         $RedirectLink = $Sender->Form->GetFormValue('RedirectLink');
         if ($MergeDiscussion) {
             $ErrorCount = 0;
             // Verify that the user has permission to perform the merge.
             $Category = CategoryModel::Categories($MergeDiscussion['CategoryID']);
             if ($Category && !$Category['PermsDiscussionsEdit']) {
                 throw PermissionException('Vanilla.Discussions.Edit');
             }
             $DiscussionModel->DefineSchema();
             $MaxNameLength = GetValue('Length', $DiscussionModel->Schema->GetField('Name'));
             // Assign the comments to the new discussion record
             $DiscussionModel->SQL->Update('Comment')->Set('DiscussionID', $MergeDiscussionID)->WhereIn('DiscussionID', $DiscussionIDs)->Put();
             $CommentModel = new CommentModel();
             foreach ($Discussions as $Discussion) {
                 if ($Discussion['DiscussionID'] == $MergeDiscussionID) {
                     continue;
                 }
                 // Create a comment out of the discussion.
                 $Comment = ArrayTranslate($Discussion, array('Body', 'Format', 'DateInserted', 'InsertUserID', 'InsertIPAddress', 'DateUpdated', 'UpdateUserID', 'UpdateIPAddress', 'Attributes', 'Spam', 'Likes', 'Abuse'));
                 $Comment['DiscussionID'] = $MergeDiscussionID;
                 $CommentModel->Validation->Results(TRUE);
                 $CommentID = $CommentModel->Save($Comment);
                 if ($CommentID) {
                     // Move any attachments (FileUpload plugin awareness)
                     if (class_exists('MediaModel')) {
                         $MediaModel = new MediaModel();
                         $MediaModel->Reassign($Discussion['DiscussionID'], 'discussion', $CommentID, 'comment');
                     }
                     if ($RedirectLink) {
                         // The discussion needs to be changed to a moved link.
                         $RedirectDiscussion = array('Name' => SliceString(sprintf(T('Merged: %s'), $Discussion['Name']), $MaxNameLength), 'Type' => 'redirect', 'Body' => FormatString(T('This discussion has been <a href="{url,html}">merged</a>.'), array('url' => DiscussionUrl($MergeDiscussion))), 'Format' => 'Html');
                         $DiscussionModel->SetField($Discussion['DiscussionID'], $RedirectDiscussion);
                         $CommentModel->UpdateCommentCount($Discussion['DiscussionID']);
                         $CommentModel->RemovePageCache($Discussion['DiscussionID']);
                     } else {
                         // Delete discussion that was merged.
                         $DiscussionModel->Delete($Discussion['DiscussionID']);
                     }
                 } else {
                     $Sender->InformMessage($CommentModel->Validation->ResultsText());
                     $ErrorCount++;
                 }
             }
             // Update counts on all affected discussions.
             $CommentModel->UpdateCommentCount($MergeDiscussionID);
             $CommentModel->RemovePageCache($MergeDiscussionID);
             // Clear selections
             Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedDiscussions', FALSE);
             ModerationController::InformCheckedDiscussions($Sender);
             if ($ErrorCount == 0) {
                 $Sender->JsonTarget('', '', 'Refresh');
             }
         }
     }
     $Sender->Render('MergeDiscussions', '', 'plugins/SplitMerge');
 }
Example #10
0
function WritePromotedContent($Content, $Sender)
{
    static $UserPhotoFirst = NULL;
    if ($UserPhotoFirst === NULL) {
        $UserPhotoFirst = C('Vanilla.Comment.UserPhotoFirst', TRUE);
    }
    $ContentType = GetValue('ItemType', $Content);
    $ContentID = GetValue("{$ContentType}ID", $Content);
    $Author = GetValue('Author', $Content);
    switch (strtolower($ContentType)) {
        case 'comment':
            $ContentURL = CommentUrl($Content);
            break;
        case 'discussion':
            $ContentURL = DiscussionUrl($Content);
            break;
    }
    ?>
   <div id="<?php 
    echo "Promoted_{$ContentType}_{$ContentID}";
    ?>
" class="<?php 
    echo CssClass($Content);
    ?>
">
      <div class="AuthorWrap">
         <span class="Author">
            <?php 
    if ($UserPhotoFirst) {
        echo UserPhoto($Author);
        echo UserAnchor($Author, 'Username');
    } else {
        echo UserAnchor($Author, 'Username');
        echo UserPhoto($Author);
    }
    $Sender->FireEvent('AuthorPhoto');
    ?>
         </span>
         <span class="AuthorInfo">
            <?php 
    echo ' ' . WrapIf(htmlspecialchars(GetValue('Title', $Author)), 'span', array('class' => 'MItem AuthorTitle'));
    echo ' ' . WrapIf(htmlspecialchars(GetValue('Location', $Author)), 'span', array('class' => 'MItem AuthorLocation'));
    $Sender->FireEvent('AuthorInfo');
    ?>
         </span>   
      </div>
      <div class="Meta CommentMeta CommentInfo">
         <span class="MItem DateCreated">
            <?php 
    echo Anchor(Gdn_Format::Date($Content['DateInserted'], 'html'), $Permalink, 'Permalink', array('rel' => 'nofollow'));
    ?>
         </span>
         <?php 
    // Include source if one was set
    if ($Source = GetValue('Source', $Content)) {
        echo Wrap(sprintf(T('via %s'), T($Source . ' Source', $Source)), 'span', array('class' => 'MItem Source'));
    }
    $Sender->FireEvent('ContentInfo');
    ?>
      </div>
      <div class="Title"><?php 
    echo Anchor(Gdn_Format::Text($Content['Name'], FALSE), $ContentURL, 'DiscussionLink');
    ?>
</div>
      <div class="Body"><?php 
    echo Anchor(strip_tags(Gdn_Format::To($Content['Body'], $Content['Format'])), $ContentURL, 'BodyLink');
    ?>
</div>
   </div>
<?php 
}
Example #11
0
 public function notifyNewDiscussion($DiscussionID)
 {
     if (!c('Vanilla.QueueNotifications')) {
         throw forbiddenException('NotifyNewDiscussion');
     }
     if (!$this->Request->isPostBack()) {
         throw forbiddenException('GET');
     }
     // Grab the discussion.
     $Discussion = $this->DiscussionModel->getID($DiscussionID);
     if (!$Discussion) {
         throw notFoundException('Discussion');
     }
     if (val('Notified', $Discussion) != ActivityModel::SENT_PENDING) {
         die('Not pending');
     }
     // Mark the notification as in progress.
     $this->DiscussionModel->setField($DiscussionID, 'Notified', ActivityModel::SENT_INPROGRESS);
     $discussionType = val('Type', $Discussion);
     if ($discussionType) {
         $Code = "HeadlineFormat.Discussion.{$discussionType}";
     } else {
         $Code = 'HeadlineFormat.Discussion';
     }
     $HeadlineFormat = t($Code, '{ActivityUserID,user} started a new discussion: <a href="{Url,html}">{Data.Name,text}</a>');
     $Category = CategoryModel::categories(val('CategoryID', $Discussion));
     $Activity = array('ActivityType' => 'Discussion', 'ActivityUserID' => $Discussion->InsertUserID, 'HeadlineFormat' => $HeadlineFormat, 'RecordType' => 'Discussion', 'RecordID' => $DiscussionID, 'Route' => DiscussionUrl($Discussion), 'Data' => array('Name' => $Discussion->Name, 'Category' => val('Name', $Category)));
     $ActivityModel = new ActivityModel();
     $this->DiscussionModel->NotifyNewDiscussion($Discussion, $ActivityModel, $Activity);
     $ActivityModel->SaveQueue();
     $this->DiscussionModel->setField($DiscussionID, 'Notified', ActivityModel::SENT_OK);
     die('OK');
 }
 public function incrementNewDiscussion($Discussion)
 {
     if (is_numeric($Discussion)) {
         $Discussion = $this->getID($Discussion);
     }
     if (!$Discussion) {
         return;
     }
     $this->SQL->update('Category')->set('CountDiscussions', 'CountDiscussions + 1', false)->set('LastDiscussionID', val('DiscussionID', $Discussion))->set('LastCommentID', null)->set('LastDateInserted', val('DateInserted', $Discussion))->where('CategoryID', val('CategoryID', $Discussion))->put();
     $Category = CategoryModel::categories(val('CategoryID', $Discussion));
     if ($Category) {
         CategoryModel::SetCache($Category['CategoryID'], array('CountDiscussions' => $Category['CountDiscussions'] + 1, 'LastDiscussionID' => val('DiscussionID', $Discussion), 'LastCommentID' => null, 'LastDateInserted' => val('DateInserted', $Discussion), 'LastTitle' => Gdn_Format::text(val('Name', $Discussion, t('No Title'))), 'LastUserID' => val('InsertUserID', $Discussion), 'LastDiscussionUserID' => val('InsertUserID', $Discussion), 'LastUrl' => DiscussionUrl($Discussion, false, '//') . '#latest'));
     }
 }
 public function IncrementNewDiscussion($Discussion)
 {
     if (is_numeric($Discussion)) {
         $Discussion = $this->GetID($Discussion);
     }
     if (!$Discussion) {
         return;
     }
     $this->SQL->Update('Category')->Set('CountDiscussions', 'CountDiscussions + 1', FALSE)->Set('LastDiscussionID', GetValue('DiscussionID', $Discussion))->Set('LastCommentID', NULL)->Set('LastDateInserted', GetValue('DateInserted', $Discussion))->Where('CategoryID', GetValue('CategoryID', $Discussion))->Put();
     $Category = CategoryModel::Categories(GetValue('CategoryID', $Discussion));
     if ($Category) {
         CategoryModel::SetCache($Category['CategoryID'], array('CountDiscussions' => $Category['CountDiscussions'] + 1, 'LastDiscussionID' => GetValue('DiscussionID', $Discussion), 'LastCommentID' => NULL, 'LastDateInserted' => GetValue('DateInserted', $Discussion), 'LastTitle' => Gdn_Format::Text(GetValue('Name', $Discussion, T('No Title'))), 'LastUserID' => GetValue('InsertUserID', $Discussion), 'LastDiscussionUserID' => GetValue('InsertUserID', $Discussion), 'LastUrl' => DiscussionUrl($Discussion, FALSE, '//') . '#latest'));
     }
 }
 /**
  * Form to ask for the destination of the move, confirmation and permission check.
  */
 public function ConfirmDiscussionMoves($DiscussionID = NULL)
 {
     $Session = Gdn::Session();
     $this->Form = new Gdn_Form();
     $DiscussionModel = new DiscussionModel();
     $this->Title(T('Confirm'));
     if ($DiscussionID) {
         $CheckedDiscussions = (array) $DiscussionID;
         $ClearSelection = FALSE;
     } else {
         $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array());
         if (!is_array($CheckedDiscussions)) {
             $CheckedDiscussions = array();
         }
         $ClearSelection = TRUE;
     }
     $DiscussionIDs = $CheckedDiscussions;
     $CountCheckedDiscussions = count($DiscussionIDs);
     $this->SetData('CountCheckedDiscussions', $CountCheckedDiscussions);
     // Check for edit permissions on each discussion
     $AllowedDiscussions = array();
     $DiscussionData = $DiscussionModel->SQL->Select('DiscussionID, Name, DateLastComment, CategoryID')->From('Discussion')->WhereIn('DiscussionID', $DiscussionIDs)->Get();
     $DiscussionData = Gdn_DataSet::Index($DiscussionData->ResultArray(), array('DiscussionID'));
     foreach ($DiscussionData as $DiscussionID => $Discussion) {
         $Category = CategoryModel::Categories($Discussion['CategoryID']);
         if ($Category && $Category['PermsDiscussionsEdit']) {
             $AllowedDiscussions[] = $DiscussionID;
         }
     }
     $this->SetData('CountAllowed', count($AllowedDiscussions));
     $CountNotAllowed = $CountCheckedDiscussions - count($AllowedDiscussions);
     $this->SetData('CountNotAllowed', $CountNotAllowed);
     if ($this->Form->AuthenticatedPostBack()) {
         // Retrieve the category id
         $CategoryID = $this->Form->GetFormValue('CategoryID');
         $Category = CategoryModel::Categories($CategoryID);
         $RedirectLink = $this->Form->GetFormValue('RedirectLink');
         // User must have add permission on the target category
         if (!$Category['PermsDiscussionsAdd']) {
             throw ForbiddenException('@' . T('You do not have permission to add discussions to this category.'));
         }
         // Iterate and move.
         foreach ($AllowedDiscussions as $DiscussionID) {
             // Create the shadow redirect.
             if ($RedirectLink) {
                 $Discussion = GetValue($DiscussionID, $DiscussionData);
                 $DiscussionModel->DefineSchema();
                 $MaxNameLength = GetValue('Length', $DiscussionModel->Schema->GetField('Name'));
                 $RedirectDiscussion = array('Name' => SliceString(sprintf(T('Moved: %s'), $Discussion['Name']), $MaxNameLength), 'DateInserted' => $Discussion['DateLastComment'], 'Type' => 'redirect', 'CategoryID' => $Discussion['CategoryID'], 'Body' => FormatString(T('This discussion has been <a href="{url,html}">moved</a>.'), array('url' => DiscussionUrl($Discussion))), 'Format' => 'Html', 'Closed' => TRUE);
                 $RedirectID = $DiscussionModel->Save($RedirectDiscussion);
                 if (!$RedirectID) {
                     $this->Form->SetValidationResults($DiscussionModel->ValidationResults());
                     break;
                 }
             }
             $DiscussionModel->SetField($DiscussionID, 'CategoryID', $CategoryID);
         }
         // Clear selections.
         if ($ClearSelection) {
             Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedDiscussions', FALSE);
             ModerationController::InformCheckedDiscussions($this);
         }
         if ($this->Form->ErrorCount() == 0) {
             $this->JsonTarget('', '', 'Refresh');
         }
     }
     $this->Render();
 }
Example #15
0
 /**
  * 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 Search($Search, $Offset = 0, $Limit = 20)
 {
     // If there are no searches then return an empty array.
     if (trim($Search) == '') {
         return array();
     }
     // Figure out the exact search mode.
     if ($this->ForceSearchMode) {
         $SearchMode = $this->ForceSearchMode;
     } else {
         $SearchMode = strtolower(C('Garden.Search.Mode', 'matchboolean'));
     }
     if ($SearchMode == 'matchboolean') {
         if (strpos($Search, '+') !== FALSE || strpos($Search, '-') !== FALSE) {
             $SearchMode = 'boolean';
         } else {
             $SearchMode = 'match';
         }
     } else {
         $this->_SearchMode = $SearchMode;
     }
     if ($ForceDatabaseEngine = C('Database.ForceStorageEngine')) {
         if (strcasecmp($ForceDatabaseEngine, 'myisam') != 0) {
             $SearchMode = 'like';
         }
     }
     if (strlen($Search) <= 4) {
         $SearchMode = 'like';
     }
     $this->_SearchMode = $SearchMode;
     $this->FireEvent('Search');
     if (count($this->_SearchSql) == 0) {
         return array();
     }
     // Perform the search by unioning all of the sql together.
     $Sql = $this->SQL->Select()->From('_TBL_ s')->OrderBy('s.DateInserted', 'desc')->Limit($Limit, $Offset)->GetSelect();
     $Sql = str_replace($this->Database->DatabasePrefix . '_TBL_', "(\n" . implode("\nunion all\n", $this->_SearchSql) . "\n)", $Sql);
     $this->EventArguments['Search'] = $Search;
     $this->FireEvent('AfterBuildSearchQuery');
     if ($this->_SearchMode == 'like') {
         $Search = '%' . $Search . '%';
     }
     foreach ($this->_Parameters as $Key => $Value) {
         $this->_Parameters[$Key] = $Search;
     }
     $Parameters = $this->_Parameters;
     $this->Reset();
     $this->SQL->Reset();
     $Result = $this->Database->Query($Sql, $Parameters)->ResultArray();
     foreach ($Result as $Key => $Value) {
         if (isset($Value['Summary'])) {
             $Value['Summary'] = Condense(Gdn_Format::To($Value['Summary'], $Value['Format']));
             $Result[$Key] = $Value;
         }
         switch ($Value['RecordType']) {
             case 'Discussion':
                 $Discussion = ArrayTranslate($Value, array('PrimaryID' => 'DiscussionID', 'Title' => 'Name', 'CategoryID'));
                 $Result[$Key]['Url'] = DiscussionUrl($Discussion, 1);
                 break;
         }
     }
     return $Result;
 }
Example #17
0
    /**
     * Insert sorting tabs after first comment.
     */
    public function DiscussionController_BeforeCommentDisplay_Handler($Sender)
    {
        //		if (!C('Plugins.Voting.Enabled'))
        //			return;
        $AnswerCount = $Sender->Discussion->CountComments - 1;
        $Type = GetValue('Type', $Sender->EventArguments, 'Comment');
        if ($Type == 'Comment' && !GetValue('VoteHeaderWritten', $Sender)) {
            //$Type != 'Comment' && $AnswerCount > 0) {
            ?>
		<li class="Item">
			<div class="VotingSort">
			<?php 
            echo Wrap($AnswerCount . ' ' . Plural($AnswerCount, 'Comment', 'Comments'), 'strong');
            echo ' sorted by ' . Anchor('Votes', Url(DiscussionUrl($Sender->Discussion) . '?Sort=popular', TRUE), '', array('rel' => 'nofollow', 'class' => self::CommentSort() == 'popular' ? 'Active' : '')) . ' ' . Anchor('Date Added', Url(DiscussionUrl($Sender->Discussion) . '?Sort=date', TRUE), '', array('rel' => 'nofollow', 'class' => self::CommentSort() == 'date' ? 'Active' : ''));
            ?>
			</div>
		</li>
		<?php 
            $Sender->VoteHeaderWritten = TRUE;
        }
    }
echo T('Follows');
?>
</td>
            <td><?php 
echo T('Views');
?>
</td>
         </tr>
      </thead>
      <tbody>
         <?php 
foreach ($this->Data['DiscussionData'] as $Discussion) {
    ?>
         <tr>
            <th><?php 
    echo Anchor(htmlspecialchars($Discussion->Name), DiscussionUrl($Discussion));
    ?>
</th>
            <td><?php 
    echo number_format($Discussion->CountComments);
    ?>
</td>
            <td><?php 
    echo number_format($Discussion->CountBookmarks);
    ?>
</td>
            <td><?php 
    echo number_format($Discussion->CountViews);
    ?>
</td>
         </tr>
 /**
  * Form to ask for the destination of the move, confirmation and permission check.
  */
 public function confirmDiscussionMoves($DiscussionID = null)
 {
     $Session = Gdn::session();
     $this->Form = new Gdn_Form();
     $DiscussionModel = new DiscussionModel();
     $CategoryModel = new CategoryModel();
     $this->title(t('Confirm'));
     if ($DiscussionID) {
         $CheckedDiscussions = (array) $DiscussionID;
         $ClearSelection = false;
     } else {
         $CheckedDiscussions = Gdn::userModel()->getAttribute($Session->User->UserID, 'CheckedDiscussions', array());
         if (!is_array($CheckedDiscussions)) {
             $CheckedDiscussions = array();
         }
         $ClearSelection = true;
     }
     $DiscussionIDs = $CheckedDiscussions;
     $CountCheckedDiscussions = count($DiscussionIDs);
     $this->setData('CountCheckedDiscussions', $CountCheckedDiscussions);
     // Check for edit permissions on each discussion
     $AllowedDiscussions = array();
     $DiscussionData = $DiscussionModel->SQL->select('DiscussionID, Name, DateLastComment, CategoryID, CountComments')->from('Discussion')->whereIn('DiscussionID', $DiscussionIDs)->get();
     $DiscussionData = Gdn_DataSet::Index($DiscussionData->resultArray(), array('DiscussionID'));
     foreach ($DiscussionData as $DiscussionID => $Discussion) {
         $Category = CategoryModel::categories($Discussion['CategoryID']);
         if ($Category && $Category['PermsDiscussionsEdit']) {
             $AllowedDiscussions[] = $DiscussionID;
         }
     }
     $this->setData('CountAllowed', count($AllowedDiscussions));
     $CountNotAllowed = $CountCheckedDiscussions - count($AllowedDiscussions);
     $this->setData('CountNotAllowed', $CountNotAllowed);
     if ($this->Form->authenticatedPostBack()) {
         // Retrieve the category id
         $CategoryID = $this->Form->getFormValue('CategoryID');
         $Category = CategoryModel::categories($CategoryID);
         $RedirectLink = $this->Form->getFormValue('RedirectLink');
         // User must have add permission on the target category
         if (!$Category['PermsDiscussionsAdd']) {
             throw forbiddenException('@' . t('You do not have permission to add discussions to this category.'));
         }
         $AffectedCategories = array();
         // Iterate and move.
         foreach ($AllowedDiscussions as $DiscussionID) {
             $Discussion = val($DiscussionID, $DiscussionData);
             // Create the shadow redirect.
             if ($RedirectLink) {
                 $DiscussionModel->defineSchema();
                 $MaxNameLength = val('Length', $DiscussionModel->Schema->GetField('Name'));
                 $RedirectDiscussion = array('Name' => SliceString(sprintf(t('Moved: %s'), $Discussion['Name']), $MaxNameLength), 'DateInserted' => $Discussion['DateLastComment'], 'Type' => 'redirect', 'CategoryID' => $Discussion['CategoryID'], 'Body' => formatString(t('This discussion has been <a href="{url,html}">moved</a>.'), array('url' => DiscussionUrl($Discussion))), 'Format' => 'Html', 'Closed' => true);
                 // Pass a forced input formatter around this exception.
                 if (c('Garden.ForceInputFormatter')) {
                     $InputFormat = c('Garden.InputFormatter');
                     saveToConfig('Garden.InputFormatter', 'Html', false);
                 }
                 $RedirectID = $DiscussionModel->save($RedirectDiscussion);
                 // Reset the input formatter
                 if (c('Garden.ForceInputFormatter')) {
                     saveToConfig('Garden.InputFormatter', $InputFormat, false);
                 }
                 if (!$RedirectID) {
                     $this->Form->setValidationResults($DiscussionModel->validationResults());
                     break;
                 }
             }
             $DiscussionModel->setField($DiscussionID, 'CategoryID', $CategoryID);
             if (!isset($AffectedCategories[$Discussion['CategoryID']])) {
                 $AffectedCategories[$Discussion['CategoryID']] = array(-1, -$Discussion['CountComments']);
             } else {
                 $AffectedCategories[$Discussion['CategoryID']][0] -= 1;
                 $AffectedCategories[$Discussion['CategoryID']][1] -= $Discussion['CountComments'];
             }
             if (!isset($AffectedCategories[$CategoryID])) {
                 $AffectedCategories[$CategoryID] = array(1, $Discussion['CountComments']);
             } else {
                 $AffectedCategories[$CategoryID][0] += 1;
                 $AffectedCategories[$CategoryID][1] += $Discussion['CountComments'];
             }
         }
         // Update recent posts and counts on all affected categories.
         foreach ($AffectedCategories as $CategoryID => $Counts) {
             $CategoryModel->SetRecentPost($CategoryID);
             $CategoryModel->SQL->update('Category')->set('CountDiscussions', 'CountDiscussions' . ($Counts[0] < 0 ? ' - ' : ' + ') . abs($Counts[0]), false)->set('CountComments', 'CountComments' . ($Counts[1] < 0 ? ' - ' : ' + ') . abs($Counts[1]), false)->where('CategoryID', $CategoryID)->put();
         }
         // Clear selections.
         if ($ClearSelection) {
             Gdn::userModel()->saveAttribute($Session->UserID, 'CheckedDiscussions', false);
             ModerationController::InformCheckedDiscussions($this);
         }
         if ($this->Form->errorCount() == 0) {
             $this->jsonTarget('', '', 'Refresh');
         }
     }
     $this->render();
 }
Example #20
0
$Contents = $this->_Content;
echo '<ul class="DataList Compact BlogList">';
foreach ($Contents as $Content) {
    static $UserPhotoFirst = NULL;
    if ($UserPhotoFirst === NULL) {
        $UserPhotoFirst = C('Vanilla.Comment.UserPhotoFirst', TRUE);
    }
    $ContentType = GetValue('ItemType', $Content);
    $ContentID = GetValue("{$ContentType}ID", $Content);
    $Author = GetValue('Author', $Content);
    switch (strtolower($ContentType)) {
        case 'comment':
            $ContentURL = CommentUrl($Content);
            break;
        case 'discussion':
            $ContentURL = DiscussionUrl($Content);
            break;
    }
    ?>
   <li id="<?php 
    echo "{$ContentType}_{$ContentID}";
    ?>
" class="Item">
     <h3><?php 
    echo Anchor(Gdn_Format::Text($Content['Name'], FALSE), $ContentURL);
    ?>
</h3>
     <div class="Item-Header">
       <div class="AuthorWrap">
         <span class="Author">
            <?php 
Example #21
0
    /**
     * Writes a discussion in table row format.
     */
    function WriteDiscussionRow($Discussion, &$Sender, &$Session, $Alt2)
    {
        if (!property_exists($Sender, 'CanEditDiscussions')) {
            $Sender->CanEditDiscussions = GetValue('PermsDiscussionsEdit', CategoryModel::Categories($Discussion->CategoryID)) && C('Vanilla.AdminCheckboxes.Use');
        }
        $CssClass = CssClass($Discussion);
        $DiscussionUrl = $Discussion->Url;
        if ($Session->UserID) {
            $DiscussionUrl .= '#latest';
        }
        $Sender->EventArguments['DiscussionUrl'] =& $DiscussionUrl;
        $Sender->EventArguments['Discussion'] =& $Discussion;
        $Sender->EventArguments['CssClass'] =& $CssClass;
        $First = UserBuilder($Discussion, 'First');
        if ($Discussion->LastUserID) {
            $Last = UserBuilder($Discussion, 'Last');
        } else {
            $Last = $First;
        }
        //   $Sender->EventArguments['FirstUser'] = &$First;
        //   $Sender->EventArguments['LastUser'] = &$Last;
        //
        //   $Sender->FireEvent('BeforeDiscussionName');
        $DiscussionName = $Discussion->Name;
        if ($DiscussionName == '') {
            $DiscussionName = T('Blank Discussion Topic');
        }
        $Sender->EventArguments['DiscussionName'] =& $DiscussionName;
        $Discussion->CountPages = ceil($Discussion->CountComments / $Sender->CountCommentsPerPage);
        $FirstPageUrl = DiscussionUrl($Discussion, 1);
        $LastPageUrl = DiscussionUrl($Discussion, FALSE) . '#latest';
        ?>
<tr id="Discussion_<?php 
        echo $Discussion->DiscussionID;
        ?>
" class="<?php 
        echo $CssClass;
        ?>
">
   <?php 
        echo AdminCheck($Discussion, array('<td class="CheckBoxColumn"><div class="Wrap">', '</div></td>'));
        ?>
	<td class="DiscussionName">
		<div class="Wrap">
         <span class="Options">
            <?php 
        echo OptionsList($Discussion);
        echo BookmarkButton($Discussion);
        ?>
         </span>
			<?php 
        echo Anchor($DiscussionName, $DiscussionUrl, 'Title') . ' ';
        $Sender->FireEvent('AfterDiscussionTitle');
        WriteMiniPager($Discussion);
        echo NewComments($Discussion);
        if ($Sender->Data('_ShowCategoryLink', TRUE)) {
            echo CategoryLink($Discussion, ' ' . T('in') . ' ');
        }
        // Other stuff that was in the standard view that you may want to display:
        echo '<div class="Meta Meta-Discussion">';
        WriteTags($Discussion);
        echo '</div>';
        //			if ($Source = GetValue('Source', $Discussion))
        //				echo ' '.sprintf(T('via %s'), T($Source.' Source', $Source));
        //
        ?>
		</div>
	</td>
	<td class="BlockColumn BlockColumn-User FirstUser">
		<div class="Block Wrap">
			<?php 
        echo UserPhoto($First, array('Size' => 'Small'));
        echo UserAnchor($First, 'UserLink BlockTitle');
        echo '<div class="Meta">';
        echo Anchor(Gdn_Format::Date($Discussion->FirstDate, 'html'), $FirstPageUrl, 'CommentDate MItem');
        echo '</div>';
        ?>
		</div>
   </td>
	<td class="BigCount CountComments">
      <div class="Wrap">
         <?php 
        // Exact Number
        // echo number_format($Discussion->CountComments);
        // Round Number
        echo BigPlural($Discussion->CountComments, '%s comment');
        ?>
      </div>
	</td>
	<td class="BigCount CountViews">
      <div class="Wrap">
         <?php 
        // Exact Number
        // echo number_format($Discussion->CountViews);
        // Round Number
        echo BigPlural($Discussion->CountViews, '%s view');
        ?>
      </div>
	</td>
	<td class="BlockColumn BlockColumn-User LastUser">
		<div class="Block Wrap">
			<?php 
        if ($Last) {
            echo UserPhoto($Last, array('Size' => 'Small'));
            echo UserAnchor($Last, 'UserLink BlockTitle');
            echo '<div class="Meta">';
            echo Anchor(Gdn_Format::Date($Discussion->LastDate, 'html'), $LastPageUrl, 'CommentDate MItem');
            echo '</div>';
        } else {
            echo '&nbsp;';
        }
        ?>
		</div>
	</td>
</tr>
<?php 
    }
Example #22
0
 /**
  * Modifies category data before it is returned.
  *
  * Adds CountAllDiscussions column to each category representing the sum of
  * discussions within this category as well as all subcategories.
  * 
  * @since 2.0.17
  * @access public
  *
  * @param object $Data SQL result.
  */
 public static function AddCategoryColumns($Data)
 {
     $Result =& $Data->Result();
     $Result2 = $Result;
     foreach ($Result as &$Category) {
         if (!property_exists($Category, 'CountAllDiscussions')) {
             $Category->CountAllDiscussions = $Category->CountDiscussions;
         }
         if (!property_exists($Category, 'CountAllComments')) {
             $Category->CountAllComments = $Category->CountComments;
         }
         // Calculate the following field.
         $Following = !((bool) GetValue('Archived', $Category) || (bool) GetValue('Unfollow', $Category));
         $Category->Following = $Following;
         $DateMarkedRead = GetValue('DateMarkedRead', $Category);
         $UserDateMarkedRead = GetValue('UserDateMarkedRead', $Category);
         if (!$DateMarkedRead) {
             $DateMarkedRead = $UserDateMarkedRead;
         } elseif ($UserDateMarkedRead && Gdn_Format::ToTimestamp($UserDateMarkedRead) > Gdn_Format::ToTimeStamp($DateMarkedRead)) {
             $DateMarkedRead = $UserDateMarkedRead;
         }
         // Set appropriate Last* columns.
         SetValue('LastTitle', $Category, GetValue('LastDiscussionTitle', $Category, NULL));
         $LastDateInserted = GetValue('LastDateInserted', $Category, NULL);
         if (GetValue('LastCommentUserID', $Category) == NULL) {
             SetValue('LastCommentUserID', $Category, GetValue('LastDiscussionUserID', $Category, NULL));
             SetValue('DateLastComment', $Category, GetValue('DateLastDiscussion', $Category, NULL));
             SetValue('LastUserID', $Category, GetValue('LastDiscussionUserID', $Category, NULL));
             $LastDiscussion = ArrayTranslate($Category, array('LastDiscussionID' => 'DiscussionID', 'CategoryID' => 'CategoryID', 'LastTitle' => 'Name'));
             SetValue('LastUrl', $Category, DiscussionUrl($LastDiscussion, FALSE, '//') . '#latest');
             if (is_null($LastDateInserted)) {
                 SetValue('LastDateInserted', $Category, GetValue('DateLastDiscussion', $Category, NULL));
             }
         } else {
             $LastDiscussion = ArrayTranslate($Category, array('LastDiscussionID' => 'DiscussionID', 'CategoryID' => 'CategoryID', 'LastTitle' => 'Name'));
             SetValue('LastUserID', $Category, GetValue('LastCommentUserID', $Category, NULL));
             SetValue('LastUrl', $Category, DiscussionUrl($LastDiscussion, FALSE, '//') . '#latest');
             if (is_null($LastDateInserted)) {
                 SetValue('LastDateInserted', $Category, GetValue('DateLastComment', $Category, NULL));
             }
         }
         $LastDateInserted = GetValue('LastDateInserted', $Category, NULL);
         if ($DateMarkedRead) {
             if ($LastDateInserted) {
                 $Category->Read = Gdn_Format::ToTimestamp($DateMarkedRead) >= Gdn_Format::ToTimestamp($LastDateInserted);
             } else {
                 $Category->Read = TRUE;
             }
         } else {
             $Category->Read = FALSE;
         }
         foreach ($Result2 as $Category2) {
             if ($Category2->TreeLeft > $Category->TreeLeft && $Category2->TreeRight < $Category->TreeRight) {
                 $Category->CountAllDiscussions += $Category2->CountDiscussions;
                 $Category->CountAllComments += $Category2->CountComments;
             }
         }
     }
 }
Example #23
0
 /**
  * Join external records to an array.
  *
  * @param array &$Data The data to join.
  * In order to join records each row must have the a RecordType and RecordID column.
  * @param string $Column The name of the column to put the record in.
  * If this is blank then the record will be merged into the row.
  * @param bool $Unset Whether or not to unset rows that don't have a record.
  * @since 2.3
  */
 function joinRecords(&$Data, $Column = '', $Unset = false)
 {
     $IDs = array();
     $AllowedCats = DiscussionModel::CategoryPermissions();
     if ($AllowedCats === false) {
         // This user does not have permission to view anything.
         $Data = array();
         return;
     }
     // Gather all of the ids to fetch.
     foreach ($Data as &$Row) {
         if (!$Row['RecordType']) {
             continue;
         }
         $RecordType = ucfirst(StringEndsWith($Row['RecordType'], '-Total', true, true));
         $Row['RecordType'] = $RecordType;
         $ID = $Row['RecordID'];
         $IDs[$RecordType][$ID] = $ID;
     }
     // Fetch all of the data in turn.
     $JoinData = array();
     foreach ($IDs as $RecordType => $RecordIDs) {
         if ($RecordType == 'Comment') {
             Gdn::SQL()->Select('d.Name, d.CategoryID')->Join('Discussion d', 'd.DiscussionID = r.DiscussionID');
         }
         $Rows = Gdn::SQL()->Select('r.*')->WhereIn($RecordType . 'ID', array_values($RecordIDs))->Get($RecordType . ' r')->ResultArray();
         $JoinData[$RecordType] = Gdn_DataSet::Index($Rows, array($RecordType . 'ID'));
     }
     // Join the rows.
     $Unsets = array();
     foreach ($Data as $Index => &$Row) {
         $RecordType = $Row['RecordType'];
         $ID = $Row['RecordID'];
         if (!isset($JoinData[$RecordType][$ID])) {
             if ($Unset) {
                 $Unsets[] = $Index;
             }
             continue;
             // orphaned?
         }
         $Record = $JoinData[$RecordType][$ID];
         if ($AllowedCats !== true) {
             // Check to see if the user has permission to view this record.
             $CategoryID = GetValue('CategoryID', $Record, -1);
             if (!in_array($CategoryID, $AllowedCats)) {
                 $Unsets[] = $Index;
                 continue;
             }
         }
         switch ($RecordType) {
             case 'Discussion':
                 $Url = DiscussionUrl($Record, '', '/') . '#latest';
                 break;
             case 'Comment':
                 $Url = CommentUrl($Record, '/');
                 $Record['Name'] = sprintf(T('Re: %s'), $Record['Name']);
                 break;
             default:
                 $Url = '';
         }
         $Record['Url'] = $Url;
         if ($Column) {
             $Row[$Column] = $Record;
         } else {
             $Row = array_merge($Row, $Record);
         }
     }
     foreach ($Unsets as $Index) {
         unset($Data[$Index]);
     }
     // Join the users.
     Gdn::UserModel()->JoinUsers($Data, array('InsertUserID'));
     if (!empty($Unsets)) {
         $Data = array_values($Data);
     }
 }
Example #24
0
    /**
     * Writes a discussion in table row format.
     */
    function writeDiscussionRow($Discussion, $Sender, $Session)
    {
        if (!property_exists($Sender, 'CanEditDiscussions')) {
            $Sender->CanEditDiscussions = val('PermsDiscussionsEdit', CategoryModel::categories($Discussion->CategoryID)) && c('Vanilla.AdminCheckboxes.Use');
        }
        $CssClass = CssClass($Discussion);
        $DiscussionUrl = $Discussion->Url;
        if ($Session->UserID) {
            $DiscussionUrl .= '#latest';
        }
        $Sender->EventArguments['DiscussionUrl'] =& $DiscussionUrl;
        $Sender->EventArguments['Discussion'] =& $Discussion;
        $Sender->EventArguments['CssClass'] =& $CssClass;
        $First = UserBuilder($Discussion, 'First');
        if ($Discussion->LastUserID) {
            $Last = UserBuilder($Discussion, 'Last');
        } else {
            $Last = $First;
        }
        $Sender->EventArguments['FirstUser'] =& $First;
        $Sender->EventArguments['LastUser'] =& $Last;
        $Sender->fireEvent('BeforeDiscussionName');
        $DiscussionName = $Discussion->Name;
        // If there are no word character detected in the title treat it as if it is blank.
        if (!preg_match('/\\w/u', $DiscussionName)) {
            $DiscussionName = t('Blank Discussion Topic');
        }
        $Sender->EventArguments['DiscussionName'] =& $DiscussionName;
        static $FirstDiscussion = true;
        if (!$FirstDiscussion) {
            $Sender->fireEvent('BetweenDiscussion');
        } else {
            $FirstDiscussion = false;
        }
        $Discussion->CountPages = ceil($Discussion->CountComments / $Sender->CountCommentsPerPage);
        $FirstPageUrl = DiscussionUrl($Discussion, 1);
        $LastPageUrl = DiscussionUrl($Discussion, val('CountPages', $Discussion)) . '#latest';
        ?>
        <tr id="Discussion_<?php 
        echo $Discussion->DiscussionID;
        ?>
" class="<?php 
        echo $CssClass;
        ?>
">
            <?php 
        $Sender->fireEvent('BeforeDiscussionContent');
        ?>
            <?php 
        echo AdminCheck($Discussion, array('<td class="CheckBoxColumn"><div class="Wrap">', '</div></td>'));
        ?>
            <td class="DiscussionName">
                <div class="Wrap">
         <span class="Options">
            <?php 
        echo OptionsList($Discussion);
        echo BookmarkButton($Discussion);
        ?>
         </span>
                    <?php 
        $Sender->fireEvent('BeforeDiscussionTitle');
        echo anchor($DiscussionName, $DiscussionUrl, 'Title') . ' ';
        $Sender->fireEvent('AfterDiscussionTitle');
        WriteMiniPager($Discussion);
        echo NewComments($Discussion);
        if ($Sender->data('_ShowCategoryLink', true)) {
            echo CategoryLink($Discussion, ' ' . t('in') . ' ');
        }
        // Other stuff that was in the standard view that you may want to display:
        echo '<div class="Meta Meta-Discussion">';
        WriteTags($Discussion);
        echo '</div>';
        //			if ($Source = val('Source', $Discussion))
        //				echo ' '.sprintf(t('via %s'), t($Source.' Source', $Source));
        //
        ?>
                </div>
            </td>
            <td class="BlockColumn BlockColumn-User FirstUser">
                <div class="Block Wrap">
                    <?php 
        echo userPhoto($First, array('Size' => 'Small'));
        echo userAnchor($First, 'UserLink BlockTitle');
        echo '<div class="Meta">';
        echo anchor(Gdn_Format::date($Discussion->FirstDate, 'html'), $FirstPageUrl, 'CommentDate MItem');
        echo '</div>';
        ?>
                </div>
            </td>
            <td class="BigCount CountComments">
                <div class="Wrap">
                    <?php 
        // Exact Number
        // echo number_format($Discussion->CountComments);
        // Round Number
        echo BigPlural($Discussion->CountComments, '%s comment');
        ?>
                </div>
            </td>
            <td class="BigCount CountViews">
                <div class="Wrap">
                    <?php 
        // Exact Number
        // echo number_format($Discussion->CountViews);
        // Round Number
        echo BigPlural($Discussion->CountViews, '%s view');
        ?>
                </div>
            </td>
            <td class="BlockColumn BlockColumn-User LastUser">
                <div class="Block Wrap">
                    <?php 
        if ($Last) {
            echo userPhoto($Last, array('Size' => 'Small'));
            echo userAnchor($Last, 'UserLink BlockTitle');
            echo '<div class="Meta">';
            echo anchor(Gdn_Format::date($Discussion->LastDate, 'html'), $LastPageUrl, 'CommentDate MItem');
            echo '</div>';
        } else {
            echo '&nbsp;';
        }
        ?>
                </div>
            </td>
        </tr>
    <?php 
    }
 /**
  *
  *
  * @param $Sender
  * @param $Args
  * @throws Gdn_UserException
  */
 public function commentModel_afterSaveComment_handler($Sender, $Args)
 {
     if (!$this->socialSharing()) {
         return;
     }
     if (!$this->accessToken()) {
         return;
     }
     $ShareFacebook = valr('FormPostValues.ShareFacebook', $Args);
     if ($ShareFacebook) {
         $Row = $Args['FormPostValues'];
         $DiscussionModel = new DiscussionModel();
         $Discussion = $DiscussionModel->getID(val('DiscussionID', $Row));
         if (!$Discussion) {
             die('no discussion');
         }
         $Url = DiscussionUrl($Discussion, '', true);
         $Message = SliceParagraph(Gdn_Format::plainText($Row['Body'], $Row['Format']), 160);
         if ($this->accessToken()) {
             $R = $this->api('/me/feed', array('link' => $Url, 'message' => $Message));
         }
     }
 }
Example #26
0
 /**
  * Create or update a comment.
  *
  * @since 2.0.0
  * @access public
  * 
  * @param int $DiscussionID Unique ID to add the comment to. If blank, this method will throw an error.
  */
 public function Comment($DiscussionID = '')
 {
     // Get $DiscussionID from RequestArgs if valid
     if ($DiscussionID == '' && count($this->RequestArgs)) {
         if (is_numeric($this->RequestArgs[0])) {
             $DiscussionID = $this->RequestArgs[0];
         }
     }
     // If invalid $DiscussionID, get from form.
     $this->Form->SetModel($this->CommentModel);
     $DiscussionID = is_numeric($DiscussionID) ? $DiscussionID : $this->Form->GetFormValue('DiscussionID', 0);
     // Set discussion data
     $this->DiscussionID = $DiscussionID;
     $this->Discussion = $Discussion = $this->DiscussionModel->GetID($DiscussionID);
     // Is this an embedded comment being posted to a discussion that doesn't exist yet?
     $vanilla_type = $this->Form->GetFormValue('vanilla_type', '');
     $vanilla_url = $this->Form->GetFormValue('vanilla_url', '');
     $vanilla_category_id = $this->Form->GetFormValue('vanilla_category_id', '');
     $Attributes = array('ForeignUrl' => $vanilla_url);
     $vanilla_identifier = $this->Form->GetFormValue('vanilla_identifier', '');
     // Only allow vanilla identifiers of 32 chars or less - md5 if larger
     if (strlen($vanilla_identifier) > 32) {
         $Attributes['vanilla_identifier'] = $vanilla_identifier;
         $vanilla_identifier = md5($vanilla_identifier);
     }
     if (!$Discussion && $vanilla_url != '' && $vanilla_identifier != '') {
         $Discussion = $Discussion = $this->DiscussionModel->GetForeignID($vanilla_identifier, $vanilla_type);
         if ($Discussion) {
             $this->DiscussionID = $DiscussionID = $Discussion->DiscussionID;
             $this->Form->SetValue('DiscussionID', $DiscussionID);
         }
     }
     // If so, create it!
     if (!$Discussion && $vanilla_url != '' && $vanilla_identifier != '') {
         // Add these values back to the form if they exist!
         $this->Form->AddHidden('vanilla_identifier', $vanilla_identifier);
         $this->Form->AddHidden('vanilla_type', $vanilla_type);
         $this->Form->AddHidden('vanilla_url', $vanilla_url);
         $this->Form->AddHidden('vanilla_category_id', $vanilla_category_id);
         $PageInfo = FetchPageInfo($vanilla_url);
         $Title = GetValue('Title', $PageInfo, '');
         if ($Title == '') {
             $Title = T('Undefined discussion subject.');
         }
         $Description = GetValue('Description', $PageInfo, '');
         $Images = GetValue('Images', $PageInfo, array());
         $LinkText = T('EmbededDiscussionLinkText', 'Read the full story here');
         $Body = FormatString('
      <div class="EmbeddedContent">{Image}<strong>{Title}</strong>
         <p>{Excerpt}</p>
         <p><a href="{Url}">{LinkText}</a></p>
         <div class="ClearFix"></div>
      </div>', array('Title' => $Title, 'Excerpt' => $Description, 'Image' => count($Images) > 0 ? Img(GetValue(0, $Images), array('class' => 'LeftAlign')) : '', 'Url' => $vanilla_url, 'LinkText' => $LinkText));
         if ($Body == '') {
             $Body = $vanilla_url;
         }
         if ($Body == '') {
             $Body = T('Undefined discussion body.');
         }
         // Validate the CategoryID for inserting.
         $Category = CategoryModel::Categories($vanilla_category_id);
         if (!$Category) {
             $vanilla_category_id = C('Vanilla.Embed.DefaultCategoryID', 0);
             if ($vanilla_category_id <= 0) {
                 // No default category defined, so grab the first non-root category and use that.
                 $vanilla_category_id = $this->DiscussionModel->SQL->Select('CategoryID')->From('Category')->Where('CategoryID >', 0)->Get()->FirstRow()->CategoryID;
                 // No categories in the db? default to 0
                 if (!$vanilla_category_id) {
                     $vanilla_category_id = 0;
                 }
             }
         } else {
             $vanilla_category_id = $Category['CategoryID'];
         }
         $SystemUserID = Gdn::UserModel()->GetSystemUserID();
         $EmbeddedDiscussionData = array('InsertUserID' => $SystemUserID, 'DateInserted' => Gdn_Format::ToDateTime(), 'UpdateUserID' => $SystemUserID, 'DateUpdated' => Gdn_Format::ToDateTime(), 'CategoryID' => $vanilla_category_id, 'ForeignID' => $vanilla_identifier, 'Type' => $vanilla_type, 'Name' => $Title, 'Body' => $Body, 'Format' => 'Html', 'Attributes' => serialize($Attributes));
         $this->EventArguments['Discussion'] = $EmbeddedDiscussionData;
         $this->FireEvent('BeforeEmbedDiscussion');
         $DiscussionID = $this->DiscussionModel->SQL->Insert('Discussion', $EmbeddedDiscussionData);
         $ValidationResults = $this->DiscussionModel->ValidationResults();
         if (count($ValidationResults) == 0 && $DiscussionID > 0) {
             $this->Form->AddHidden('DiscussionID', $DiscussionID);
             // Put this in the form so reposts won't cause new discussions.
             $this->Form->SetFormValue('DiscussionID', $DiscussionID);
             // Put this in the form values so it is used when saving comments.
             $this->SetJson('DiscussionID', $DiscussionID);
             $this->Discussion = $Discussion = $this->DiscussionModel->GetID($DiscussionID);
             // Update the category discussion count
             if ($vanilla_category_id > 0) {
                 $this->DiscussionModel->UpdateDiscussionCount($vanilla_category_id, $DiscussionID);
             }
         }
     }
     // If no discussion was found, error out
     if (!$Discussion) {
         $this->Form->AddError(T('Failed to find discussion for commenting.'));
     }
     $PermissionCategoryID = GetValue('PermissionCategoryID', $Discussion);
     // Setup head
     $this->AddJsFile('jquery.autogrow.js');
     $this->AddJsFile('post.js');
     $this->AddJsFile('autosave.js');
     // Setup comment model, $CommentID, $DraftID
     $Session = Gdn::Session();
     $CommentID = isset($this->Comment) && property_exists($this->Comment, 'CommentID') ? $this->Comment->CommentID : '';
     $DraftID = isset($this->Comment) && property_exists($this->Comment, 'DraftID') ? $this->Comment->DraftID : '';
     $this->EventArguments['CommentID'] = $CommentID;
     $this->EventArguments['DraftID'] = $DraftID;
     // Determine whether we are editing
     $Editing = $CommentID > 0 || $DraftID > 0;
     $this->EventArguments['Editing'] = $Editing;
     // If closed, cancel & go to discussion
     if ($Discussion && $Discussion->Closed == 1 && !$Editing && !$Session->CheckPermission('Vanilla.Discussions.Close', TRUE, 'Category', $PermissionCategoryID)) {
         Redirect(DiscussionUrl($Discussion));
     }
     // Add hidden IDs to form
     $this->Form->AddHidden('DiscussionID', $DiscussionID);
     $this->Form->AddHidden('CommentID', $CommentID);
     $this->Form->AddHidden('DraftID', $DraftID, TRUE);
     // Check permissions
     if ($Discussion && $Editing) {
         // Permisssion to edit
         if ($this->Comment->InsertUserID != $Session->UserID) {
             $this->Permission('Vanilla.Comments.Edit', TRUE, 'Category', $Discussion->PermissionCategoryID);
         }
         // Make sure that content can (still) be edited.
         $EditContentTimeout = C('Garden.EditContentTimeout', -1);
         $CanEdit = $EditContentTimeout == -1 || strtotime($this->Comment->DateInserted) + $EditContentTimeout > time();
         if (!$CanEdit) {
             $this->Permission('Vanilla.Comments.Edit', TRUE, 'Category', $Discussion->PermissionCategoryID);
         }
         // Make sure only moderators can edit closed things
         if ($Discussion->Closed) {
             $this->Permission('Vanilla.Comments.Edit', TRUE, 'Category', $Discussion->PermissionCategoryID);
         }
     } else {
         if ($Discussion) {
             // Permission to add
             $this->Permission('Vanilla.Comments.Add', TRUE, 'Category', $Discussion->PermissionCategoryID);
         }
     }
     if (!$this->Form->IsPostBack()) {
         // Form was validly submitted
         if (isset($this->Comment)) {
             $this->Form->SetData((array) $this->Comment);
         }
     } else {
         // Save as a draft?
         $FormValues = $this->Form->FormValues();
         $FormValues = $this->CommentModel->FilterForm($FormValues);
         if ($DraftID == 0) {
             $DraftID = $this->Form->GetFormValue('DraftID', 0);
         }
         $Type = GetIncomingValue('Type');
         $Draft = $Type == 'Draft';
         $this->EventArguments['Draft'] = $Draft;
         $Preview = $Type == 'Preview';
         if ($Draft) {
             $DraftID = $this->DraftModel->Save($FormValues);
             $this->Form->AddHidden('DraftID', $DraftID, TRUE);
             $this->Form->SetValidationResults($this->DraftModel->ValidationResults());
         } else {
             if (!$Preview) {
                 $Inserted = !$CommentID;
                 $CommentID = $this->CommentModel->Save($FormValues);
                 // The comment is now half-saved.
                 if (is_numeric($CommentID) && $CommentID > 0) {
                     if ($this->_DeliveryType == DELIVERY_TYPE_ALL) {
                         $this->CommentModel->Save2($CommentID, $Inserted, TRUE, TRUE);
                     } else {
                         $this->JsonTarget('', Url("/vanilla/post/comment2.json?commentid={$CommentID}&inserted={$Inserted}"), 'Ajax');
                     }
                     // $Discussion = $this->DiscussionModel->GetID($DiscussionID);
                     $Comment = $this->CommentModel->GetID($CommentID);
                     $this->EventArguments['Discussion'] = $Discussion;
                     $this->EventArguments['Comment'] = $Comment;
                     $this->FireEvent('AfterCommentSave');
                 } elseif ($CommentID === SPAM) {
                     $this->StatusMessage = T('Your post has been flagged for moderation.');
                 }
                 $this->Form->SetValidationResults($this->CommentModel->ValidationResults());
                 if ($CommentID > 0 && $DraftID > 0) {
                     $this->DraftModel->Delete($DraftID);
                 }
             }
         }
         // Handle non-ajax requests first:
         if ($this->_DeliveryType == DELIVERY_TYPE_ALL) {
             if ($this->Form->ErrorCount() == 0) {
                 // Make sure that this form knows what comment we are editing.
                 if ($CommentID > 0) {
                     $this->Form->AddHidden('CommentID', $CommentID);
                 }
                 // If the comment was not a draft
                 if (!$Draft) {
                     // Redirect to the new comment.
                     if ($CommentID > 0) {
                         Redirect("discussion/comment/{$CommentID}/#Comment_{$CommentID}");
                     } elseif ($CommentID == SPAM) {
                         $this->SetData('DiscussionUrl', DiscussionUrl($Discussion));
                         $this->View = 'Spam';
                     }
                 } elseif ($Preview) {
                     // If this was a preview click, create a comment shell with the values for this comment
                     $this->Comment = new stdClass();
                     $this->Comment->InsertUserID = $Session->User->UserID;
                     $this->Comment->InsertName = $Session->User->Name;
                     $this->Comment->InsertPhoto = $Session->User->Photo;
                     $this->Comment->DateInserted = Gdn_Format::Date();
                     $this->Comment->Body = ArrayValue('Body', $FormValues, '');
                     $this->AddAsset('Content', $this->FetchView('preview'));
                 } else {
                     // If this was a draft save, notify the user about the save
                     $this->InformMessage(sprintf(T('Draft saved at %s'), Gdn_Format::Date()));
                 }
             }
         } else {
             // Handle ajax-based requests
             if ($this->Form->ErrorCount() > 0) {
                 // Return the form errors
                 $this->ErrorMessage($this->Form->Errors());
             } else {
                 // Make sure that the ajax request form knows about the newly created comment or draft id
                 $this->SetJson('CommentID', $CommentID);
                 $this->SetJson('DraftID', $DraftID);
                 if ($Preview) {
                     // If this was a preview click, create a comment shell with the values for this comment
                     $this->Comment = new stdClass();
                     $this->Comment->InsertUserID = $Session->User->UserID;
                     $this->Comment->InsertName = $Session->User->Name;
                     $this->Comment->InsertPhoto = $Session->User->Photo;
                     $this->Comment->DateInserted = Gdn_Format::Date();
                     $this->Comment->Body = ArrayValue('Body', $FormValues, '');
                     $this->View = 'preview';
                 } elseif (!$Draft) {
                     // If the comment was not a draft
                     // If Editing a comment
                     if ($Editing) {
                         // Just reload the comment in question
                         $this->Offset = 1;
                         $Comments = $this->CommentModel->GetIDData($CommentID);
                         $this->SetData('Comments', $Comments);
                         // Load the discussion
                         $this->ControllerName = 'discussion';
                         $this->View = 'comments';
                         // Also define the discussion url in case this request came from the post screen and needs to be redirected to the discussion
                         $this->SetJson('DiscussionUrl', DiscussionUrl($this->Discussion) . '#Comment_' . $CommentID);
                     } else {
                         // If the comment model isn't sorted by DateInserted or CommentID then we can't do any fancy loading of comments.
                         $OrderBy = GetValueR('0.0', $this->CommentModel->OrderBy());
                         //                     $Redirect = !in_array($OrderBy, array('c.DateInserted', 'c.CommentID'));
                         //							$DisplayNewCommentOnly = $this->Form->GetFormValue('DisplayNewCommentOnly');
                         //                     if (!$Redirect) {
                         //                        // Otherwise load all new comments that the user hasn't seen yet
                         //                        $LastCommentID = $this->Form->GetFormValue('LastCommentID');
                         //                        if (!is_numeric($LastCommentID))
                         //                           $LastCommentID = $CommentID - 1; // Failsafe back to this new comment if the lastcommentid was not defined properly
                         //
                         //                        // Don't reload the first comment if this new comment is the first one.
                         //                        $this->Offset = $LastCommentID == 0 ? 1 : $this->CommentModel->GetOffset($LastCommentID);
                         //                        // Do not load more than a single page of data...
                         //                        $Limit = C('Vanilla.Comments.PerPage', 30);
                         //
                         //                        // Redirect if the new new comment isn't on the same page.
                         //                        $Redirect |= !$DisplayNewCommentOnly && PageNumber($this->Offset, $Limit) != PageNumber($Discussion->CountComments - 1, $Limit);
                         //                     }
                         //                     if ($Redirect) {
                         //                        // The user posted a comment on a page other than the last one, so just redirect to the last page.
                         //                        $this->RedirectUrl = Gdn::Request()->Url("discussion/comment/$CommentID/#Comment_$CommentID", TRUE);
                         //                     } else {
                         //                        // Make sure to load all new comments since the page was last loaded by this user
                         //								if ($DisplayNewCommentOnly)
                         $this->Offset = $this->CommentModel->GetOffset($CommentID);
                         $Comments = $this->CommentModel->GetIDData($CommentID);
                         $this->SetData('Comments', $Comments);
                         $this->SetData('NewComments', TRUE);
                         $this->ClassName = 'DiscussionController';
                         $this->ControllerName = 'discussion';
                         $this->View = 'comments';
                         //                     }
                         // Make sure to set the user's discussion watch records
                         $CountComments = $this->CommentModel->GetCount($DiscussionID);
                         $Limit = is_object($this->Data('Comments')) ? $this->Data('Comments')->NumRows() : $Discussion->CountComments;
                         $Offset = $CountComments - $Limit;
                         $this->CommentModel->SetWatch($this->Discussion, $Limit, $Offset, $CountComments);
                     }
                 } else {
                     // If this was a draft save, notify the user about the save
                     $this->InformMessage(sprintf(T('Draft saved at %s'), Gdn_Format::Date()));
                 }
                 // And update the draft count
                 $UserModel = Gdn::UserModel();
                 $CountDrafts = $UserModel->GetAttribute($Session->UserID, 'CountDrafts', 0);
                 $this->SetJson('MyDrafts', T('My Drafts'));
                 $this->SetJson('CountDrafts', $CountDrafts);
             }
         }
     }
     // Include data for FireEvent
     if (property_exists($this, 'Discussion')) {
         $this->EventArguments['Discussion'] = $this->Discussion;
     }
     if (property_exists($this, 'Comment')) {
         $this->EventArguments['Comment'] = $this->Comment;
     }
     $this->FireEvent('BeforeCommentRender');
     if ($this->DeliveryType() == DELIVERY_TYPE_DATA) {
         $Comment = $this->Data('Comments')->FirstRow(DATASET_TYPE_ARRAY);
         if ($Comment) {
             $Photo = $Comment['InsertPhoto'];
             if (strpos($Photo, '//') === FALSE) {
                 $Photo = Gdn_Upload::Url(ChangeBasename($Photo, 'n%s'));
             }
             $Comment['InsertPhoto'] = $Photo;
         }
         $this->Data = array('Comment' => $Comment);
         $this->RenderData($this->Data);
     } else {
         // Render default view.
         $this->Render();
     }
 }
 /**
  * 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();
     }
 }
Example #28
0
 public function CommentModel_AfterSaveComment_Handler($Sender, $Args)
 {
     if (!$this->SocialSharing()) {
         return;
     }
     if (!$this->AccessToken()) {
         return;
     }
     $Share = GetValueR('FormPostValues.ShareTwitter', $Args);
     if ($Share && $this->AccessToken()) {
         $Row = $Args['FormPostValues'];
         $DiscussionModel = new DiscussionModel();
         $Discussion = $DiscussionModel->GetID(GetValue('DiscussionID', $Row));
         if (!$Discussion) {
             return;
         }
         $Url = DiscussionUrl($Discussion, '', TRUE);
         $Message = SliceTwitter(Gdn_Format::PlainText($Row['Body'], $Row['Format'])) . ' ' . $Url;
         $R = $this->API('/statuses/update.json', array('status' => $Message), 'POST');
         //         decho($R);
         //         die();
         //      } else {
         //         die("$Share ".$this->AccessToken());
     }
 }
Example #29
0
 /**
  * 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;
 }
    /**
     * Alternate version of Index that uses the embed master view.
     *
     * @param int $DiscussionID Unique identifier, if discussion has been created.
     * @param string $DiscussionStub Deprecated.
     * @param int $Offset
     * @param int $Limit
     */
    public function Embed($DiscussionID = '', $DiscussionStub = '', $Offset = '', $Limit = '')
    {
        $this->Title(T('Comments'));
        // Add theme data
        $this->Theme = C('Garden.CommentsTheme', $this->Theme);
        Gdn_Theme::Section('Comments');
        // Force view options
        $this->MasterView = 'empty';
        $this->CanEditComments = FALSE;
        // Don't show the comment checkboxes on the embed comments page
        // Add some css to help with the transparent bg on embedded comments
        if ($this->Head) {
            $this->Head->AddString('<style type="text/css">
body { background: transparent !important; }
</style>');
        }
        // Javascript files & options
        $this->AddJsFile('jquery.gardenmorepager.js');
        $this->AddJsFile('jquery.autogrow.js');
        $this->RemoveJsFile('autosave.js');
        $this->AddJsFile('discussion.js');
        $this->AddDefinition('DoInform', '0');
        // Suppress inform messages on embedded page.
        $this->AddDefinition('SelfUrl', Gdn::Request()->PathAndQuery());
        $this->AddDefinition('Embedded', TRUE);
        // Define incoming variables (prefer querystring parameters over method parameters)
        $DiscussionID = is_numeric($DiscussionID) && $DiscussionID > 0 ? $DiscussionID : 0;
        $DiscussionID = GetIncomingValue('vanilla_discussion_id', $DiscussionID);
        $Offset = GetIncomingValue('Offset', $Offset);
        $Limit = GetIncomingValue('Limit', $Limit);
        $vanilla_identifier = GetIncomingValue('vanilla_identifier', '');
        // Only allow vanilla identifiers of 32 chars or less - md5 if larger
        if (strlen($vanilla_identifier) > 32) {
            $vanilla_identifier = md5($vanilla_identifier);
        }
        $vanilla_type = GetIncomingValue('vanilla_type', 'page');
        $vanilla_url = GetIncomingValue('vanilla_url', '');
        $vanilla_category_id = GetIncomingValue('vanilla_category_id', '');
        $ForeignSource = array('vanilla_identifier' => $vanilla_identifier, 'vanilla_type' => $vanilla_type, 'vanilla_url' => $vanilla_url, 'vanilla_category_id' => $vanilla_category_id);
        $this->SetData('ForeignSource', $ForeignSource);
        // Set comment sorting
        $SortComments = C('Garden.Embed.SortComments') == 'desc' ? 'desc' : 'asc';
        $this->SetData('SortComments', $SortComments);
        // Retrieve the discussion record
        $Discussion = FALSE;
        if ($DiscussionID > 0) {
            $Discussion = $this->DiscussionModel->GetID($DiscussionID);
        } else {
            if ($vanilla_identifier != '' && $vanilla_type != '') {
                $Discussion = $this->DiscussionModel->GetForeignID($vanilla_identifier, $vanilla_type);
            }
        }
        // Set discussion data if we have one for this page
        if ($Discussion) {
            $this->Permission('Vanilla.Discussions.View', TRUE, 'Category', $Discussion->PermissionCategoryID);
            $this->SetData('Discussion', $Discussion, TRUE);
            $this->SetData('DiscussionID', $Discussion->DiscussionID, TRUE);
            $this->Title($Discussion->Name);
            // Actual number of comments, excluding the discussion itself
            $ActualResponses = $Discussion->CountComments;
            // Define the query offset & limit
            if (!is_numeric($Limit) || $Limit < 0) {
                $Limit = C('Garden.Embed.CommentsPerPage', 30);
            }
            $OffsetProvided = $Offset != '';
            list($Offset, $Limit) = OffsetLimit($Offset, $Limit);
            $this->Offset = $Offset;
            if (C('Vanilla.Comments.AutoOffset')) {
                if ($ActualResponses <= $Limit) {
                    $this->Offset = 0;
                }
                if ($this->Offset == $ActualResponses) {
                    $this->Offset -= $Limit;
                }
            } else {
                if ($this->Offset == '') {
                    $this->Offset = 0;
                }
            }
            if ($this->Offset < 0) {
                $this->Offset = 0;
            }
            // Set the canonical url to have the proper page title.
            $this->CanonicalUrl(DiscussionUrl($Discussion, PageNumber($this->Offset, $Limit)));
            // Load the comments.
            $CurrentOrderBy = $this->CommentModel->OrderBy();
            if (StringBeginsWith(GetValueR('0.0', $CurrentOrderBy), 'c.DateInserted')) {
                $this->CommentModel->OrderBy('c.DateInserted ' . $SortComments);
            }
            // allow custom sort
            $this->SetData('Comments', $this->CommentModel->Get($Discussion->DiscussionID, $Limit, $this->Offset), TRUE);
            if (count($this->CommentModel->Where()) > 0) {
                $ActualResponses = FALSE;
            }
            $this->SetData('_Count', $ActualResponses);
            // Build a pager
            $PagerFactory = new Gdn_PagerFactory();
            $this->EventArguments['PagerType'] = 'MorePager';
            $this->FireEvent('BeforeBuildPager');
            $this->Pager = $PagerFactory->GetPager($this->EventArguments['PagerType'], $this);
            $this->Pager->ClientID = 'Pager';
            $this->Pager->MoreCode = 'More Comments';
            $this->Pager->Configure($this->Offset, $Limit, $ActualResponses, 'discussion/embed/' . $Discussion->DiscussionID . '/' . Gdn_Format::Url($Discussion->Name) . '/%1$s');
            $this->Pager->CurrentRecords = $this->Comments->NumRows();
            $this->FireEvent('AfterBuildPager');
        }
        // Define the form for the comment input
        $this->Form = Gdn::Factory('Form', 'Comment');
        $this->Form->Action = Url('/vanilla/post/comment/');
        $this->Form->AddHidden('CommentID', '');
        $this->Form->AddHidden('Embedded', 'true');
        // Tell the post controller that this is an embedded page (in case there are custom views it needs to pick up from a theme).
        $this->Form->AddHidden('DisplayNewCommentOnly', 'true');
        // Only load/display the new comment after posting (don't load all new comments since the page last loaded).
        // Grab the page title
        if ($this->Request->Get('title')) {
            $this->Form->SetValue('Name', $this->Request->Get('title'));
        }
        // Set existing DiscussionID for comment form
        if ($Discussion) {
            $this->Form->AddHidden('DiscussionID', $Discussion->DiscussionID);
        }
        foreach ($ForeignSource as $Key => $Val) {
            // Drop the foreign source information into the form so it can be used if creating a discussion
            $this->Form->AddHidden($Key, $Val);
            // Also drop it into the definitions so it can be picked up for stashing comments
            $this->AddDefinition($Key, $Val);
        }
        // Retrieve & apply the draft if there is one:
        $Draft = FALSE;
        if (Gdn::Session()->UserID && $Discussion) {
            $DraftModel = new DraftModel();
            $Draft = $DraftModel->Get(Gdn::Session()->UserID, 0, 1, $Discussion->DiscussionID)->FirstRow();
            $this->Form->AddHidden('DraftID', $Draft ? $Draft->DraftID : '');
        }
        if ($Draft) {
            $this->Form->SetFormValue('Body', $Draft->Body);
        } else {
            // Look in the session stash for a comment
            $StashComment = Gdn::Session()->Stash('CommentForForeignID_' . $ForeignSource['vanilla_identifier'], '', FALSE);
            if ($StashComment) {
                $this->Form->SetValue('Body', $StashComment);
                $this->Form->SetFormValue('Body', $StashComment);
            }
        }
        // Deliver JSON data if necessary
        if ($this->_DeliveryType != DELIVERY_TYPE_ALL) {
            if ($this->Discussion) {
                $this->SetJson('LessRow', $this->Pager->ToString('less'));
                $this->SetJson('MoreRow', $this->Pager->ToString('more'));
            }
            $this->View = 'comments';
        }
        // Ordering note for JS
        if ($SortComments == 'desc') {
            $this->AddDefinition('PrependNewComments', '1');
        }
        // Report the discussion id so js can use it.
        if ($Discussion) {
            $this->AddDefinition('DiscussionID', $Discussion->DiscussionID);
        }
        $this->FireEvent('BeforeDiscussionRender');
        $this->Render();
    }