function GetPropertiesFromDataSet($DataSet, &$Context) { $this->Title = FormatHtmlStringInline(ForceString($DataSet["Name"], "")); $this->Link = PrependString("http://", AppendFolder(agDOMAIN, "comments.php?DiscussionID=" . ForceInt($DataSet["DiscussionID"], 0))); $this->Id = $this->Link; $this->Published = FixDate(@$DataSet["DateCreated"]); $this->Updated = FixDate(@$DataSet["DateLastActive"]); $this->AuthorName = FormatHtmlStringInline(ForceString($DataSet["AuthUsername"], "")); $this->AuthorUrl = PrependString("http://", AppendFolder(agDOMAIN, "account.php?u=" . ForceInt($DataSet["AuthUserID"], 0))); $this->Content = $this->RemoveHtml(ForceString(@$DataSet["Body"], "")); $this->Summary = SliceString($this->Content, 200); $this->Summary = str_replace("\r\n", " ", $this->Content); $this->Content = str_replace("\r\n", "<br />", $this->Content); if (agUSE_CATEGORIES) { $this->Category = FormatStringForDisplay(ForceString($DataSet["Category"], ""), true); $this->CategoryLink = "http://" . AppendFolder(agDOMAIN, "?CategoryID=" . ForceInt($DataSet["CategoryID"], 0)); } }
/** * Eval code. * Returns array() on success. * Returns string on failure. * * @param mixed $Code * @return mixed $Result. */ private static function EvalConfigurationCode($Code) { $Lines = explode("\n", $Code); $NewLines = array(); foreach ($Lines as $Line) { $Line = trim($Line); if ($Line == '') { continue; } if (substr($Line, 0, 14) != '$Configuration') { return 'Unexpected: ' . SliceString($Line, 50); } $Tokens = token_get_all('<?php ' . $Line); $Key = array_search(';', $Tokens, True); if ($Key === False) { continue; } $Tokens = array_slice($Tokens, 0, $Key + 1); $JoinStrings = False; $Line = ''; foreach ($Tokens as $Token) { if ($JoinStrings == False) { if (is_array($Token) && $Token[0] == 309 && $Token[1] == '$Configuration') { $JoinStrings = True; } } if (!$JoinStrings) { continue; } if (is_array($Token)) { $Token = $Token[1]; } $Line .= $Token; } $NewLines[] = $Line; } if (count($NewLines) == 0) { return 'Nothing to write.'; } return $NewLines; //if (!$ErrorString) $ErrorString = 'Something funky happened.'; //return $ErrorString; }
function HighlightTrimmedString($Haystack, $Needles, $TrimLength = '') { $Highlight = '<span class="Highlight">\\1</span>'; $Pattern = '#(?!<.*?)(%s)(?![^<>]*?>)#i'; $TrimLength = ForceInt($TrimLength, 0); if ($TrimLength > 0) { $Haystack = SliceString($Haystack, $TrimLength); } $WordsToHighlight = count($Needles); if ($WordsToHighlight > 0) { $i = 0; for ($i = 0; $i < $WordsToHighlight; $i++) { if (strlen($Needles[$i]) > 2) { $CurrentWord = preg_quote($Needles[$i]); $Regex = sprintf($Pattern, $CurrentWord); $Haystack = preg_replace($Regex, $Highlight, $Haystack); } } } return $Haystack; }
break; } } elseif (!$LastPhoto) { $LastPhoto = UserPhoto($User); } } $CssClass = 'Item'; $CssClass .= $Alt ? ' Alt' : ''; $CssClass .= $Conversation->CountNewMessages > 0 ? ' New' : ''; $CssClass .= $LastPhoto != '' ? ' HasPhoto' : ''; $CssClass .= ' ' . ($Conversation->CountNewMessages <= 0 ? 'Read' : 'Unread'); $JumpToItem = $Conversation->CountMessages - $Conversation->CountNewMessages; if ($Conversation->LastFormat == 'Text') { $Message = SliceString(Gdn_Format::To($Conversation->LastBody, $Conversation->LastFormat), 100); } else { $Message = SliceString(Gdn_Format::Text(Gdn_Format::To($Conversation->LastBody, $Conversation->LastFormat), FALSE), 100); } if (StringIsNullOrEmpty(trim($Message))) { $Message = T('Blank Message'); } $this->EventArguments['Conversation'] = $Conversation; ?> <li class="<?php echo $CssClass; ?> "> <?php $Names = ''; foreach ($Conversation->Participants as $User) { $Names = ConcatSep(', ', $Names, FormatUsername($User, 'You')); }
function searchExcerpt($PlainText, $SearchTerms, $Length = 200, $Mark = true) { if (empty($SearchTerms)) { return substrWord($PlainText, 0, $Length); } if (is_string($SearchTerms)) { $SearchTerms = preg_split('`[\\s|-]+`i', $SearchTerms); } // Split the string into lines. $Lines = explode("\n", $PlainText); // Find the first line that includes a search term. foreach ($Lines as $i => &$Line) { $Line = trim($Line); if (!$Line) { continue; } foreach ($SearchTerms as $Term) { if (!$Term) { continue; } if (($Pos = mb_stripos($Line, $Term)) !== false) { $Line = substrWord($Line, $Term, $Length); if ($Mark) { return MarkString($SearchTerms, $Line); } else { return $Line; } } } } // No line was found so return the first non-blank line. foreach ($Lines as $Line) { if ($Line) { return SliceString($Line, $Length); } } return ''; }
function writeTableRow($Row, $Depth = 1) { $Children = $Row['Children']; $WriteChildren = FALSE; if (!empty($Children)) { if ($Depth + 1 >= c('Vanilla.Categories.MaxDisplayDepth')) { $WriteChildren = 'list'; } else { $WriteChildren = 'rows'; } } $H = 'h' . ($Depth + 1); ?> <tr class="<?php echo CssClass($Row); ?> "> <td class="CategoryName"> <div class="Wrap"> <?php echo GetOptions($Row); echo CategoryPhoto($Row); echo "<{$H}>"; echo anchor(htmlspecialchars($Row['Name']), $Row['Url']); Gdn::controller()->EventArguments['Category'] = $Row; Gdn::controller()->fireEvent('AfterCategoryTitle'); echo "</{$H}>"; ?> <div class="CategoryDescription"> <?php echo $Row['Description']; ?> </div> <?php if ($WriteChildren === 'list') { ?> <div class="ChildCategories"> <?php echo wrap(t('Child Categories') . ': ', 'b'); echo CategoryString($Children, $Depth + 1); ?> </div> <?php } ?> </div> </td> <td class="BigCount CountDiscussions"> <div class="Wrap"> <?php // echo "({$Row['CountDiscussions']})"; echo BigPlural($Row['CountAllDiscussions'], '%s discussion'); ?> </div> </td> <td class="BigCount CountComments"> <div class="Wrap"> <?php // echo "({$Row['CountComments']})"; echo BigPlural($Row['CountAllComments'], '%s comment'); ?> </div> </td> <td class="BlockColumn LatestPost"> <div class="Block Wrap"> <?php if ($Row['LastTitle']) { ?> <?php echo userPhoto($Row, array('Size' => 'Small', 'Px' => 'Last')); echo anchor(SliceString(Gdn_Format::text($Row['LastTitle']), 100), $Row['LastUrl'], 'BlockTitle LatestPostTitle', array('title' => html_entity_decode($Row['LastTitle']))); ?> <div class="Meta"> <?php echo userAnchor($Row, 'UserLink MItem', 'Last'); ?> <span class="Bullet">•</span> <?php echo anchor(Gdn_Format::date($Row['LastDateInserted'], 'html'), $Row['LastUrl'], 'CommentDate MItem'); if (isset($Row['LastCategoryID'])) { $LastCategory = CategoryModel::categories($Row['LastCategoryID']); echo ' <span>', sprintf('in %s', anchor($LastCategory['Name'], CategoryUrl($LastCategory, '', '//'))), '</span>'; } ?> </div> <?php } ?> </div> </td> </tr> <?php if ($WriteChildren === 'rows') { foreach ($Children as $ChildRow) { WriteTableRow($ChildRow, $Depth + 1); } } }
/** * Slices a string at a paragraph. * This function will attempt to slice a string at paragraph that is no longer than the specified maximum length. * If it can't slice the string at a paragraph it will attempt to slice on a sentence. * * Note that you should not expect this function to return a string that is always shorter than max-length. * The purpose of this function is to provide a string that is reaonably easy to consume by a human. * * @param string $String The string to slice. * @param int $MaxLength The maximum length of the string. * @param string $Suffix The suffix if the string must be sliced mid-sentence. * @return string */ function SliceParagraph($String, $MaxLength = 500, $Suffix = '…') { if ($MaxLength >= strlen($String)) { return $String; } // $String = preg_replace('`\s+\n`', "\n", $String); // See if there is a paragraph. $Pos = strrpos(SliceString($String, $MaxLength, ''), "\n\n"); if ($Pos === FALSE) { // There was no paragraph so try and split on sentences. $Sentences = preg_split('`([.!?:]\\s+)`', $String, NULL, PREG_SPLIT_DELIM_CAPTURE); $Result = ''; if (count($Sentences) > 1) { $Result = $Sentences[0] . $Sentences[1]; for ($i = 2; $i < count($Sentences); $i++) { $Sentence = $Sentences[$i]; if (strlen($Result) + strlen($Sentence) <= $MaxLength || preg_match('`[.!?:]\\s+`', $Sentence)) { $Result .= $Sentence; } else { break; } } } if ($Result) { return rtrim($Result); } // There was no sentence. Slice off the last word and call it a day. $Pos = strrpos(SliceString($String, $MaxLength, ''), ' '); if ($Pos === FALSE) { return $String . $Suffix; } else { return SliceString($String, $Pos + 1, $Suffix); } } else { return substr($String, 0, $Pos + 1); } }
/** * 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'); }
if (!defined('APPLICATION')) { exit; } $Session = Gdn::Session(); $ShowOptions = TRUE; $Alt = ''; foreach ($this->DraftData->Result() as $Draft) { $EditUrl = !is_numeric($Draft->DiscussionID) || $Draft->DiscussionID <= 0 ? '/post/editdiscussion/0/' . $Draft->DraftID : '/post/editcomment/0/' . $Draft->DraftID; $Alt = $Alt == ' Alt' ? '' : ' Alt'; ?> <li class="<?php echo 'DiscussionRow Draft' . $Alt; ?> "> <ul> <li class="Title"> <?php echo Anchor('Delete', 'vanilla/drafts/delete/' . $Draft->DraftID . '/' . $Session->TransientKey() . '?Target=' . urlencode($this->SelfUrl), 'DeleteDraft'); ?> <strong><?php echo Anchor($Draft->Name, $EditUrl, 'DraftLink'); ?> </strong> <?php echo Anchor(SliceString(Format::Text($Draft->Body), 200), $EditUrl); ?> </li> </ul> </li> <?php }
public function Gdn_Form_DropDown_Override($Form) { $FieldName =& $Form->EventArguments[0]; $DataSet =& $Form->EventArguments[1]; $Attributes =& $Form->EventArguments[2]; //$ValueField = ArrayValueI('ValueField', $Attributes, 'value'); $TextField = ArrayValueI('TextField', $Attributes, 'text'); $MaxDropDownTextField = C('Plugins.Morf.MaxLengthDropDownTextField'); if (GetIncomingValue('DeliveryType', DELIVERY_TYPE_ALL) != DELIVERY_TYPE_ALL) { $MaxTextLength = GetValue('Window', $MaxDropDownTextField); } else { $MaxTextLength = GetValue('Default', $MaxDropDownTextField); } if (is_numeric($MaxTextLength) && $MaxTextLength > 0) { if (is_object($DataSet)) { $TestValue = GetValue($TextField, $DataSet->FirstRow()); if ($TestValue !== False) { foreach ($DataSet->ResultObject() as $Data) { $S = SliceString(GetValue($TextField, $Data), $MaxTextLength); SetValue($TextField, $Data, $S); } } } elseif (is_array($DataSet)) { // ResultSet is unexpected here foreach ($DataSet as &$Value) { $Value = SliceString($Value, $MaxTextLength); } } } return $Form->DropDown($FieldName, $DataSet, $Attributes); }
function WriteTable($Results, $WriteText, $CssClass) { $String = ''; $Total = sizeof($Results); if ($Total == 0) { return $String; //return an empty string if no results } $Count = 0; //for toggling the message div if text ob_start(); ?> <div class="SphinxSearch Table"> <table> <thead> <tr> <th class="Title">Discussion</th> <th class="Starter">Starter</th> <th class="Forum">Forum</th> <th class="InfoCount">R / V</th> <th class="Latest">Latest</th> </tr> </thead> <tbody> <?php foreach ($Results as $Row) { ?> <?php $ID = 'T_' . $Count++; //unique identifer $OAuthor->Name = $Row->UserName; $OAuthor->UserID = $Row->UserID; //original author $LAuthor->Name = $Row->LastUserName; $LAuthor->UserID = $Row->LastUserID; //latest author $Row->CountCommentWatch = $Row->CountComments; //for discussion link $TitleURL = $Row->IsComment ? 'discussion/comment/' . $Row->CommentID . '/#Comment_' . $Row->CommentID : DiscussionLink($Row, FALSE); //if the comment is from the orignal discussion poster, simply link to the front page of that ?> <tr <?php echo Alternate(); ?> > <td class="Title"> <?php if ($WriteText) { ?> <span id="<?php echo $ID; ?> " class="PlusImage Toggle"></span> <?php } ?> <span class="Title"><?php echo Anchor($Row->Title . Wrap(htmlspecialchars(SliceString($Row->DiscussionBody, SS_PREVIEW_BODY_LIMIT)), 'span', array('class' => 'ToolTip')), $TitleURL, FALSE, array('class' => 'HasToolTip')); ?> </span> </td> <td class="Starter"> <?php echo UserAnchor($OAuthor); ?> <?php Anchor(Gdn_Format::Date($Row->DateInserted), $TitleURL); ?> </td> <td class="Forum"> <?php echo Anchor(Gdn_Format::Text($Row->CatName), 'categories/' . $Row->CatUrlCode); ?> </td> <td class="InfoCount"> <?php echo Gdn_Format::BigNumber($Row->CountComments); ?> / <?php echo Gdn_Format::BigNumber($Row->CountViews); ?> </td> <td class="Latest"> <?php echo UserAnchor($LAuthor) . ' on '; echo Anchor(Gdn_Format::Date($Row->DateInserted), DiscussionLink($Row, $Extended = TRUE)); ?> </td> </tr> <?php if ($WriteText) { ?> <tr id="<?php echo $ID . 'T'; ?> " style="display: none" class="ExpandText"> <td colspan="5"> <!-- Need this since this column will expand the width of the table !--> <div class="Message Excerpt"> <?php echo nl2br(SliceString($Row->Body, SS_BODY_LIMIT)); ?> </div> </td> </tr> <?php } ?> <?php } ?> </tbody> </table> <div style="clear: both"></div> </div> <?php $String = ob_get_contents(); @ob_end_clean(); return $String; }
/** * 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(); }
function SearchExcerpt($PlainText, $SearchTerms, $Length = 200, $Mark = true) { if (empty($SearchTerms)) { return substrWord($PlainText, 0, $Length); } if (is_string($SearchTerms)) { $SearchTerms = preg_split('`[\\s|-]+`i', $SearchTerms); } // Split the string into lines. $Lines = explode("\n", $PlainText); // Find the first line that includes a search term. foreach ($Lines as $i => &$Line) { $Line = trim($Line); if (!$Line) { continue; } foreach ($SearchTerms as $Term) { if (!$Term) { continue; } if (($Pos = mb_stripos($Line, $Term)) !== FALSE) { $Line = substrWord($Line, $Term, $Length); // if ($Pos + mb_strlen($Term) > $Length) { // $St = -(strlen($Line) - ($Pos - $Length / 4)); // $Pos2 = strrpos($Line, ' ', $St); // if ($Pos2 !== FALSE) // $Line = '…'.substrWord($Line, $Pos2, $Length, "!!!"); // else // $Line = '…!'.mb_substr($Line, $St, $Length); // } else { // $Line = substrWord($Line, 0, $Length, '---'); // } return MarkString($SearchTerms, $Line); } } } // No line was found so return the first non-blank line. foreach ($Lines as $Line) { if ($Line) { return SliceString($Line, $Length); } } }
if (!defined('APPLICATION')) { exit; } ?> <div class="Box BoxDrafts"> <?php echo panelHeading(T('My Drafts')); ?> <ul class="PanelInfo PanelDiscussions"> <?php foreach ($this->Data->Result() as $Draft) { $EditUrl = !is_numeric($Draft->DiscussionID) || $Draft->DiscussionID <= 0 ? '/post/editdiscussion/0/' . $Draft->DraftID : '/post/editcomment/0/' . $Draft->DraftID; ?> <li> <strong><?php echo Anchor($Draft->Name, $EditUrl); ?> </strong> <?php echo Anchor(SliceString(Gdn_Format::Text($Draft->Body), 200), $EditUrl, 'DraftCommentLink'); ?> </li> <?php } ?> <li class="ShowAll"><?php echo Anchor(T('↳ Show All'), 'drafts'); ?> </li> </ul> </div>
function WriteClassic($Results, $WriteText, $CssClass) { if (sizeof($Results) == 0) { //make sure there is something here return ''; } ob_start(); ?> <div class="SphinxSearch"> <ul class="DataList"> <?php foreach ($Results as $Row) { ?> <?php $Author->Photo = $Row->UserPhoto; $Author->Name = $Row->UserName; $Author->UserID = $Row->UserID; $TitleURL = $Row->IsComment ? 'discussion/comment/' . $Row->CommentID . '/#Comment_' . $Row->CommentID : DiscussionLink($Row, FALSE); //if the comment is from the orignal discussion poster, simply link to the front page of that ?> <li class="Item"> <div class="ItemContent"> <h4 class="Title"><?php echo Anchor($Row->Title, $TitleURL, FALSE, array('class' => 'HasToolTip')); ?> </h4> <?php if ($WriteText) { ?> <div class="Message Excerpt"> <?php //echo nl2br(SliceString($Row->Body, SS_BODY_LIMIT)); This seemed to make MARKDOWN posts look correct - JJB ?> <?php echo SliceString($Row->Body, SS_BODY_LIMIT); ?> </div> <?php } ?> <div class="Meta"> <span class="MItem"><?php echo UserPhoto($Author, array('LinkClass' => '', 'ImageClass' => 'ProfilePhotoSmall PhotoWrap')); ?> </span> <span class="MItem"><?php echo Anchor($Row->UserName, UserUrl($Author)); ?> </span> <span class="MItem"><?php echo Anchor(Gdn_Format::Date($Row->DateInserted), 'discussion/' . $Row->DiscussionID . '/' . Gdn_Format::Url($Row->Title) . '/p1'); ?> </span> <span class="MItem"><?php echo Anchor($Row->CatName, 'discussion/' . $Row->DiscussionID . '/' . Gdn_Format::Url($Row->Title) . '/p1'); ?> </span> </div> </div> </li> <?php } ?> </ul> </div> <?php $String = ob_get_contents(); @ob_end_clean(); return $String; }
if (!defined('APPLICATION')) { exit; } $Session = Gdn::Session(); $Alt = FALSE; foreach ($this->ConversationData->Result() as $Conversation) { $Alt = $Alt == TRUE ? FALSE : TRUE; $LastAuthor = UserBuilder($Conversation, 'LastMessage'); $LastPhoto = UserPhoto($LastAuthor, 'Photo'); $CssClass = 'Item'; $CssClass .= $Alt ? ' Alt' : ''; $CssClass .= $Conversation->CountNewMessages > 0 ? ' New' : ''; $CssClass .= $LastPhoto != '' ? ' HasPhoto' : ''; $JumpToItem = $Conversation->CountMessages - $Conversation->CountNewMessages; $Message = SliceString(Gdn_Format::Text($Conversation->LastMessage), 100); if (StringIsNullOrEmpty(trim($Message))) { $Message = T('Blank Message'); } ?> <li class="<?php echo $CssClass; ?> "> <?php if ($LastPhoto != '') { ?> <div class="Photo"><?php echo $LastPhoto; ?> </div>
<?php if (is_array($this->SearchResults) && count($this->SearchResults) > 0) { foreach ($this->SearchResults as $Key => $Row) { $Row = (object) $Row; $this->EventArguments['Row'] = $Row; ?> <li class="Item"> <?php $this->FireEvent('BeforeItemContent'); ?> <div class="ItemContent"> <?php echo Anchor(Gdn_Format::Text($Row->Title), $Row->Url, 'Title'); ?> <div class="Excerpt"><?php echo Anchor(nl2br(SliceString(Gdn_Format::Text($Row->Summary, FALSE), 250)), $Row->Url); ?> </div> <div class="Meta"> <span><?php printf(T('by %s'), UserAnchor($Row)); ?> </span> <span><?php echo Gdn_Format::Date($Row->DateInserted); ?> </span> <?php if (isset($Row->CategoryID)) { $Category = CategoryModel::Categories($Row->CategoryID); if ($Category !== NULL) {
if ($DoHeadings && $Category->Depth == 1) { $CatList .= '<li class="Item CategoryHeading Depth1 Category-' . $Category->UrlCode . ' ' . $CssClasses . '"> <div class="ItemContent Category">' . Gdn_Format::Text($Category->Name) . '</div>' . GetOptions($Category, $this) . ' </li>'; $Alt = FALSE; } else { $LastComment = UserBuilder($Category, 'LastComment'); $AltCss = $Alt ? ' Alt' : ''; $Alt = !$Alt; $CatList .= '<li class="Item Depth' . $Category->Depth . $AltCss . ' Category-' . $Category->UrlCode . ' ' . $CssClasses . '"> <div class="ItemContent Category ' . $CssClasses . '">' . Anchor(Gdn_Format::Text($Category->Name), '/categories/' . $Category->UrlCode, 'Title') . GetOptions($Category, $this) . Wrap($Category->Description, 'div', array('class' => 'CategoryDescription')) . '<div class="Meta"> <span class="RSS">' . Anchor(Img('applications/dashboard/design/images/rss.gif'), '/categories/' . $Category->UrlCode . '/feed.rss') . '</span> <span class="DiscussionCount">' . sprintf(Plural(number_format($Category->CountAllDiscussions), '%s discussion', '%s discussions'), $Category->CountDiscussions) . '</span> <span class="CommentCount">' . sprintf(Plural(number_format($Category->CountAllComments), '%s comment', '%s comments'), $Category->CountComments) . '</span>'; if ($Category->LastCommentID != '' && $Category->LastDiscussionTitle != '') { $CatList .= '<span class="LastDiscussionTitle">' . sprintf(T('Most recent: %1$s by %2$s'), Anchor(SliceString($Category->LastDiscussionTitle, 40), '/discussion/' . $Category->LastDiscussionID . '/' . Gdn_Format::Url($Category->LastDiscussionTitle)), UserAnchor($LastComment)) . '</span>' . '<span class="LastCommentDate">' . Gdn_Format::Date($Category->DateLastComment) . '</span>'; } // If this category is one level above the max display depth, and it // has children, add a replacement string for them. if ($MaxDisplayDepth > 0 && $Category->Depth == $MaxDisplayDepth - 1 && $Category->TreeRight - $Category->TreeLeft > 1) { $CatList .= '{ChildCategories}'; } $CatList .= '</div> </div> </li>'; } } } } // If there are any remaining child categories that have been collected, do // the replacement one last time.
<ul class="DataList SearchResults"> <?php if (method_exists($this->SearchResults, 'NumRows') && $this->SearchResults->NumRows() > 0) { foreach ($this->SearchResults->ResultObject() as $Row) { ?> <li class="Item"> <div class="ItemContent"> <?php echo Anchor(Format::Text($Row->Title), $Row->Url, 'Title'); ?> <div class="Excerpt"><?php echo Anchor(Format::Text(SliceString($Row->Summary, 250)), $Row->Url); ?> </div> <div class="Meta"> <span><?php printf(T('Comment by %s'), UserAnchor($Row)); ?> </span> <span><?php echo Format::Date($Row->DateInserted); ?> </span> <span><?php echo Anchor(T('permalink'), $Row->Url); ?> </span> </div> </div> </li> <?php
/** * 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(); }
<?php foreach ($this->Data('Conversations') as $Row) { ?> <li id="Conversation_<?php echo $Row['ConversationID']; ?> " class="Item"> <?php $JumpToItem = $Row['CountMessages'] - $Row['CountNewMessages']; $Url = "/messages/{$Row['ConversationID']}/#Item_{$JumpToItem}"; if ($SubjectsVisible && $Row['Subject']) { $Message = htmlspecialchars($Row['Title']); } elseif ($Row['Format'] == 'Text') { $Message = SliceString(Gdn_Format::To($Row['LastMessage'], $Conversation['Format']), 100); } else { $Message = SliceString(Gdn_Format::Text(Gdn_Format::To($Row['LastMessage'], $Row['Format']), FALSE), 100); } if (StringIsNullOrEmpty(trim($Message))) { $Message = T('Blank Message'); } echo Anchor($Message, $Url, 'ConversationLink'); ?> <div class="Meta"> <span class="MItem Participants"> <?php $First = TRUE; foreach ($Row['Participants'] as $User) { if ($First) { $First = FALSE; } else { echo ', ';
function WriteDiscussion($Discussion, &$Sender, &$Session) { $CssClass = CssClass($Discussion); $DiscussionUrl = $Discussion->Url; $Category = CategoryModel::Categories($Discussion->CategoryID); if ($Session->UserID) { $DiscussionUrl .= '#latest'; } $Sender->EventArguments['DiscussionUrl'] =& $DiscussionUrl; $Sender->EventArguments['Discussion'] =& $Discussion; $Sender->EventArguments['CssClass'] =& $CssClass; $First = UserBuilder($Discussion, 'First'); $Last = UserBuilder($Discussion, 'Last'); $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; static $FirstDiscussion = TRUE; if (!$FirstDiscussion) { $Sender->FireEvent('BetweenDiscussion'); } else { $FirstDiscussion = FALSE; } $Discussion->CountPages = ceil($Discussion->CountComments / $Sender->CountCommentsPerPage); ?> <li id="Discussion_<?php echo $Discussion->DiscussionID; ?> " class="<?php echo $CssClass; ?> "> <?php if (!property_exists($Sender, 'CanEditDiscussions')) { $Sender->CanEditDiscussions = GetValue('PermsDiscussionsEdit', CategoryModel::Categories($Discussion->CategoryID)) && C('Vanilla.AdminCheckboxes.Use'); } $Sender->FireEvent('BeforeDiscussionContent'); // WriteOptions($Discussion, $Sender, $Session); ?> <span class="Options"> <?php echo OptionsList($Discussion); echo BookmarkButton($Discussion); ?> </span> <div class="ItemContent Discussion"> <div class="Title"> <?php echo AdminCheck($Discussion, array('', ' ')); WriteTags($Discussion); echo Anchor(SliceString($DiscussionName, 80), $DiscussionUrl, '', array('title' => $DiscussionName)); if (C('Vanilla.Categories.Use') && $Category) { echo Wrap(Anchor(htmlspecialchars($Discussion->Category), CategoryUrl($Discussion->CategoryUrlCode)), 'span', array('class' => 'Tag MItem Category ' . $Category['CssClass'])); } $Sender->FireEvent('AfterDiscussionTitle'); echo NewComments($Discussion); ?> </div> <div class="Meta Meta-Discussion"> <div class="row"> <div class="col-lg-4"> <span class="MItem LastCommentBy"><?php echo UserAnchor($First); ?> </span> </div> <div class="col-lg-3"> <span class="MItem MCount ViewCount"><?php printf(PluralTranslate($Discussion->CountViews, '%s view html', '%s views html', '%s view', '%s views'), BigPlural($Discussion->CountViews, '%s view')); ?> </span> <span class="MItem MCount CommentCount"><?php printf(PluralTranslate($Discussion->CountComments, '%s comment html', '%s comments html', '%s comment', '%s comments'), BigPlural($Discussion->CountComments, '%s comment')); ?> </span> <span class="MItem MCount DiscussionScore Hidden"><?php $Score = $Discussion->Score; if ($Score == '') { $Score = 0; } printf(Plural($Score, '%s point', '%s points', BigPlural($Score, '%s point'))); ?> </span> </div> <div class="col-lg-5 LastPost"> <?php $Sender->FireEvent('AfterCountMeta'); if ($Discussion->LastCommentID != '') { echo ' <span class="MItem LastCommentBy">' . sprintf(T('Latest: %1$s'), UserAnchor($Last)) . '</span> '; echo '• <span class="MItem LastCommentDate">' . Gdn_Format::DateFull($Discussion->LastDate, 'html') . '</span>'; //echo ' <span class="MItem LastCommentDate">'.Gdn_Format::Date($Discussion->LastDate, 'html').'</span>'; } else { echo ' <span class="MItem LastCommentBy">' . sprintf(T('Latest: %1$s'), UserAnchor($First)) . '</span> '; echo '• <span class="MItem LastCommentDate">' . Gdn_Format::DateFull($Discussion->FirstDate, 'html'); if ($Source = GetValue('Source', $Discussion)) { echo ' ' . sprintf(T('via %s'), T($Source . ' Source', $Source)); } echo '</span> '; } $Sender->FireEvent('DiscussionMeta'); ?> </div> </div> </div> </div> <?php $Sender->FireEvent('AfterDiscussionContent'); ?> </li> <?php }
?> <li class="Item" rel="<?php echo Url("/messages/{$Row['ConversationID']}#latest"); ?> "> <div class="Author Photo"><?php echo UserPhoto($PhotoUser); ?> </div> <div class="ItemContent"> <b class="Subject"><?php echo Anchor($Subject, "/messages/{$Row['ConversationID']}#latest"); ?> </b> <?php $Excerpt = SliceString(Gdn_Format::PlainText($Row['LastBody'], $Row['LastFormat']), 80); echo Wrap(nl2br($Excerpt), 'div', array('class' => 'Excerpt')); ?> <div class="Meta"> <?php echo ' <span class="MItem">' . Plural($Row['CountMessages'], '%s message', '%s messages') . '</span> '; if ($Row['CountNewMessages'] > 0) { echo ' <strong class="HasNew"> ' . Plural($Row['CountNewMessages'], '%s new', '%s new') . '</strong> '; } echo ' <span class="MItem">' . Gdn_Format::Date($Row['LastDateInserted']) . '</span> '; ?> </div> </div> </li> <?php }
} foreach ($this->CommentData->Result() as $Comment) { $Permalink = '/discussion/comment/' . $Comment->CommentID . '/#Comment_' . $Comment->CommentID; $User = UserBuilder($Comment, 'Insert'); $this->EventArguments['User'] = $User; ?> <li class="Item"> <?php $this->FireEvent('BeforeItemContent'); ?> <div class="ItemContent"> <?php echo Anchor(Gdn_Format::Text($Comment->DiscussionName), $Permalink, 'Title'); ?> <div class="Excerpt"><?php echo Anchor(SliceString(Gdn_Format::Text(Gdn_Format::To($Comment->Body, $Comment->Format), FALSE), 250), $Permalink); ?> </div> <div class="Meta"> <span><?php printf(T('Comment by %s'), UserAnchor($User)); ?> </span> <span><?php echo Gdn_Format::Date($Comment->DateInserted); ?> </span> <span><?php echo Anchor(T('permalink'), $Permalink); ?> </span>
/** * Saves the user's About field. * * @param int The UserID to save. * @param string The about message being saved. */ public function SaveAbout($UserID, $About) { $About = substr($About, 0, 1000); $this->SQL->Update($this->Name)->Set('About', $About)->Where('UserID', $UserID)->Put(); if (strlen($About) > 500) { $About = SliceString($About, 500) . '...'; } }
} if (count($Category->ChildIDs) > 0) { foreach ($Category->ChildIDs as $SubcatRow) { if (isset($lastPosts[$SubcatRow])) { $lastPostsInner[] = $lastPosts[$SubcatRow]; } } foreach ($lastPostsInner as $key => $row) { $postDates[$key] = $row['LastDateInserted']; } } if (count($lastPostsInner) > 1) { array_multisort($postDates, SORT_DESC, $lastPostsInner); } if (count($lastPostsInner) > 0) { $CatList .= '<div class="MItem LastDiscussionTitle">' . Anchor(Gdn_Format::Text(SliceString($lastPostsInner[0]['LastTitle'], 40)), $lastPostsInner[0]['LastUrl']) . '</div>' . '<div class="MItem LastCommentDate">' . Anchor($lastPostsInner[0]['LastName'], 'profile/' . $lastPostsInner[0]['LastUserID'] . '/' . $lastPostsInner[0]['LastName']) . ' • ' . Gdn_Format::DateFull($lastPostsInner[0]['LastDateInserted'], 'html') . '</div>'; } $CatList .= '</div> </div> </div> </li>'; } } } } // If there are any remaining child categories that have been collected, do // the replacement one last time. if ($ChildCategories != '') { $CatList = str_replace('{ChildCategories}', '<span class="ChildCategories">' . Wrap(T('Child Categories:'), 'b') . ' ' . $ChildCategories . '</span>', $CatList); }
/** * Examines the page at $Url for title, description & images. Be sure to check the resultant array for any Exceptions that occurred while retrieving the page. * @param string $Url The url to examine. * @param integer $Timeout How long to allow for this request. Default Garden.SocketTimeout or 1, 0 to never timeout. Default is 0. * @return array an array containing Url, Title, Description, Images (array) and Exception (if there were problems retrieving the page). */ function FetchPageInfo($Url, $Timeout = 0) { $PageInfo = array('Url' => $Url, 'Title' => '', 'Description' => '', 'Images' => array(), 'Exception' => FALSE); try { $PageHtml = ProxyRequest($Url, $Timeout, TRUE); $Dom = new DOMDocument(); @$Dom->loadHTML($PageHtml); // Page Title $TitleNodes = $Dom->getElementsByTagName('title'); $PageInfo['Title'] = $TitleNodes->length > 0 ? $TitleNodes->item(0)->nodeValue : ''; // Page Description $MetaNodes = $Dom->getElementsByTagName('meta'); foreach ($MetaNodes as $MetaNode) { if (strtolower($MetaNode->getAttribute('name')) == 'description') { $PageInfo['Description'] = $MetaNode->getAttribute('content'); } } // Keep looking for page description? if ($PageInfo['Description'] == '') { $PNodes = $Dom->getElementsByTagName('p'); foreach ($PNodes as $PNode) { $PVal = $PNode->nodeValue; if (strlen($PVal) > 90) { $PageInfo['Description'] = $PVal; break; } } } if (strlen($PageInfo['Description']) > 400) { $PageInfo['Description'] = SliceString($PageInfo['Description'], 400); } // Page Images (retrieve first 3 if bigger than 100w x 300h) $Images = array(); $ImageNodes = $Dom->getElementsByTagName('img'); $i = 0; foreach ($ImageNodes as $ImageNode) { $Images[] = AbsoluteSource($ImageNode->getAttribute('src'), $Url); } // Sort by size, biggest one first $ImageSort = array(); // Only look at first 10 images (speed!) $i = 0; foreach ($Images as $Image) { $i++; if ($i > 10) { break; } list($Width, $Height, $Type, $Attributes) = getimagesize($Image); $Diag = (int) floor(sqrt($Width * $Width + $Height * $Height)); if (!array_key_exists($Diag, $ImageSort)) { $ImageSort[$Diag] = $Image; } } krsort($ImageSort); $PageInfo['Images'] = array_values($ImageSort); } catch (Exception $ex) { $PageInfo['Exception'] = $ex; } return $PageInfo; }
$Alt = FALSE; $SubjectsVisible = C('Conversations.Subjects.Visible'); foreach ($this->ConversationData->Result() as $Conversation) { $Alt = $Alt == TRUE ? FALSE : TRUE; $LastAuthor = UserBuilder($Conversation, 'LastMessage'); $LastPhoto = UserPhoto($LastAuthor, 'Photo'); $CssClass = 'Item'; $CssClass .= $Alt ? ' Alt' : ''; $CssClass .= $Conversation->CountNewMessages > 0 ? ' New' : ''; $CssClass .= $LastPhoto != '' ? ' HasPhoto' : ''; $JumpToItem = $Conversation->CountMessages - $Conversation->CountNewMessages; if ($Conversation->Format == 'Text') $Message = nl2br(SliceString(Gdn_Format::To($Conversation->LastMessage, $Conversation->Format), 100)); else $Message = nl2br(SliceString(Gdn_Format::Text(Gdn_Format::To($Conversation->LastMessage, $Conversation->Format), FALSE), 100)); if (StringIsNullOrEmpty(trim($Message))) $Message = T('Blank Message'); $this->EventArguments['Conversation'] = $Conversation; ?> <li class="<?php echo $CssClass; ?>"> <?php $Names = ''; $PhotoUser = NULL; foreach ($Conversation->Participants as $User) { if (GetValue('UserID', $User) == Gdn::Session()->UserID) continue; $Names = ConcatSep(', ', $Names, GetValue('Name', $User));
$Class = trim($Class); $Name = $Session->UserID == $Conversation->LastMessageUserID ? 'You' : $Conversation->LastMessageName; $JumpToItem = $Conversation->CountMessages - $Conversation->CountNewMessages; ?> <li<?php echo $Class == '' ? '' : ' class="' . $Class . '"'; ?> > <?php $LastAuthor = UserBuilder($Conversation, 'LastMessage'); echo UserPhoto($LastAuthor, 'Photo'); ?> <div> <?php echo UserAnchor($LastAuthor, 'Name'); echo Anchor(SliceString(Format::Text($Conversation->LastMessage), 100), '/messages/' . $Conversation->ConversationID . '/#Item_' . $JumpToItem, 'Message'); echo '<div class="Meta">'; echo Format::Date($Conversation->DateLastMessage); echo '<span>•</span>'; printf(Gdn::Translate(Plural($Conversation->CountMessages, '%s message', '%s messages')), $Conversation->CountMessages); if ($Conversation->CountNewMessages > 0) { echo '<span>•</span>'; echo '<em>'; printf(Gdn::Translate('%s new'), $Conversation->CountNewMessages); echo '</em>'; } echo '</div>'; ?> </div> </li> <?php
/** * 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; $CountCheckedDiscussions = count($DiscussionIDs); $Discussions = $DiscussionModel->SQL->whereIn('DiscussionID', $DiscussionIDs)->get('Discussion')->resultArray(); // Make sure none of the selected discussions are ghost redirects. $discussionTypes = array_column($Discussions, 'Type'); if (in_array('redirect', $discussionTypes)) { throw new Gdn_UserException('You cannot merge redirects.', 400); } // Check that the user has permission to edit all discussions foreach ($Discussions as $discussion) { if (!DiscussionModel::canEdit($discussion)) { throw permissionException('@' . t('You do not have permission to edit all of the discussions you are trying to merge.')); } } $Sender->setData('DiscussionIDs', $DiscussionIDs); $Sender->setData('CountCheckedDiscussions', $CountCheckedDiscussions); $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 = val('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'); }