public function pluginController_quoteMention_create($sender, $discussionID, $commentID, $username) { $sender->deliveryMethod(DELIVERY_METHOD_JSON); $user = Gdn::userModel()->getByUsername($username); $discussionModel = new DiscussionModel(); $discussion = $discussionModel->getID($discussionID); if (!$user || !$discussion) { throw notFoundException(); } // Make sure this endpoint can't be used to snoop around. $sender->permission('Vanilla.Discussions.View', true, 'Category', $discussion->PermissionCategoryID); // Find the previous comment of the mentioned user in this discussion. $item = Gdn::sql()->getWhere('Comment', ['DiscussionID' => $discussion->DiscussionID, 'InsertUserID' => $user->UserID, 'CommentID <' => $commentID], 'CommentID', 'desc', 1)->firstRow(); // The items ID in the DOM used for highlighting. if ($item) { $target = '#Comment_' . $item->CommentID; // The mentioned user might be the discussion creator. } elseif ($discussion->InsertUserID == $user->UserID) { $item = $discussion; $target = '#Discussion_' . $item->DiscussionID; } if (!$item) { // A success response code always means that a comment was found. $sender->statusCode(404); } $sender->renderData($item ? ['html' => nl2br(sliceString(Gdn_Format::plainText($item->Body, $item->Format), c('QuoteMention.MaxLength', 400))), 'target' => $target] : []); }
/** * * * @param $Name * @param string $Code * @param string $Url */ public function addLabel($Name, $Code = '', $Url = '') { if ($Code == '') { $Code = Gdn_Format::url(ucwords(trim(Gdn_Format::plainText($Name)))); } $this->_Labels[] = array('Name' => $Name, 'Code' => $Code, 'Url' => $Url); }
/** * Grabs all new notifications and adds them to the sender's inform queue. * * This method gets called by dashboard's hooks file to display new * notifications on every pageload. * * @since 2.0.18 * @access public * * @param Gdn_Controller $Sender The object calling this method. */ public static function informNotifications($Sender) { $Session = Gdn::session(); if (!$Session->isValid()) { return; } $ActivityModel = new ActivityModel(); // Get five pending notifications. $Where = array('NotifyUserID' => Gdn::session()->UserID, 'Notified' => ActivityModel::SENT_PENDING); // If we're in the middle of a visit only get very recent notifications. $Where['DateUpdated >'] = Gdn_Format::toDateTime(strtotime('-5 minutes')); $Activities = $ActivityModel->getWhere($Where, 0, 5)->resultArray(); $ActivityIDs = array_column($Activities, 'ActivityID'); $ActivityModel->setNotified($ActivityIDs); $Sender->EventArguments['Activities'] =& $Activities; $Sender->fireEvent('InformNotifications'); foreach ($Activities as $Activity) { if ($Activity['Photo']) { $UserPhoto = anchor(img($Activity['Photo'], array('class' => 'ProfilePhotoMedium')), $Activity['Url'], 'Icon'); } else { $UserPhoto = ''; } $Excerpt = Gdn_Format::plainText($Activity['Story']); $ActivityClass = ' Activity-' . $Activity['ActivityType']; $Sender->informMessage($UserPhoto . Wrap($Activity['Headline'], 'div', array('class' => 'Title')) . Wrap($Excerpt, 'div', array('class' => 'Excerpt')), 'Dismissable AutoDismiss' . $ActivityClass . ($UserPhoto == '' ? '' : ' HasIcon')); } }
/** * Homepage & single addon view. * * @param string $ID The addon to view. * @throws Exception Addon not found. */ public function index($ID = '') { if ($ID != '') { $Addon = $this->AddonModel->getSlug($ID, true); if (!is_array($Addon)) { throw notFoundException('Addon'); } else { $this->addCssFile('confidence.css'); $AddonID = $Addon['AddonID']; $this->setData($Addon); $Description = val('Description', $Addon); if ($Description) { $this->Head->addTag('meta', array('name' => 'description', 'content' => Gdn_Format::plainText($Description, false))); } $this->addCssFile('fancyzoom.css'); $this->addJsFile('fancyzoom.js'); $this->addJsFile('addon.js'); $PictureModel = new Gdn_Model('AddonPicture'); $this->PictureData = $PictureModel->getWhere(array('AddonID' => $AddonID)); $DiscussionModel = new DiscussionModel(); $this->DiscussionData = $DiscussionModel->get(0, 50, array('AddonID' => $AddonID)); $this->View = 'addon'; $this->title($this->data('Name') . ' ' . $this->data('Version')); // Set the canonical url. $this->canonicalUrl(url('/addon/' . AddonModel::slug($Addon, false), true)); $this->loadConfidenceRecord($Addon); } } else { $this->View = 'browse'; $this->browse(); return; } $this->addModule('AddonHelpModule'); $this->setData('_Types', AddonModel::$Types); $this->setData('_TypesPlural', AddonModel::$TypesPlural); $this->render(); }
/** * * * @param PostController $Sender * @param type $RecordType * @param type $ID * @throws type */ public function postController_twitter_create($Sender, $RecordType, $ID) { if (!$this->socialReactions()) { throw permissionException(); } // if (!Gdn::request()->isPostBack()) // throw permissionException('Javascript'); $Row = GetRecord($RecordType, $ID, true); if ($Row) { // Grab the tweet message. switch (strtolower($RecordType)) { case 'discussion': $Message = Gdn_Format::plainText($Row['Name'], 'Text'); break; case 'comment': default: $Message = Gdn_Format::plainText($Row['Body'], $Row['Format']); } $Elips = '...'; $Message = preg_replace('`\\s+`', ' ', $Message); // if (function_exists('normalizer_is_normalized')) { // // Slice the string to 119 characters (21 reservered for the url. // if (!normalizer_is_normalized($Message)) // $Message = Normalizer::normalize($Message, Normalizer::FORM_D); // $Elips = Normalizer::normalize($Elips, Normalizer::FORM_D); // } $Max = 140; $LinkLen = 22; $Max -= $LinkLen; $Message = SliceParagraph($Message, $Max); if (strlen($Message) > $Max) { $Message = substr($Message, 0, $Max - strlen($Elips)) . $Elips; } // echo $Message.strlen($Message); if ($this->accessToken()) { Gdn::controller()->setData('Message', $Message); $Message .= ' ' . $Row['ShareUrl']; $R = $this->api('/statuses/update.json', array('status' => $Message), 'POST'); $Sender->setJson('R', $R); $Sender->informMessage(t('Thanks for sharing!')); } else { $Get = array('text' => $Message, 'url' => $Row['ShareUrl']); $Url = "https://twitter.com/share?" . http_build_query($Get); redirect($Url); } } $Sender->render('Blank', 'Utility', 'Dashboard'); }
/** * Default single discussion display. * * @since 2.0.0 * @access public * * @param int $DiscussionID Unique discussion ID * @param string $DiscussionStub URL-safe title slug * @param int $Page The current page of comments */ public function index($DiscussionID = '', $DiscussionStub = '', $Page = '') { // Setup head $Session = Gdn::session(); $this->addJsFile('jquery.autosize.min.js'); $this->addJsFile('autosave.js'); $this->addJsFile('discussion.js'); Gdn_Theme::section('Discussion'); // Load the discussion record $DiscussionID = is_numeric($DiscussionID) && $DiscussionID > 0 ? $DiscussionID : 0; if (!array_key_exists('Discussion', $this->Data)) { $this->setData('Discussion', $this->DiscussionModel->getID($DiscussionID), true); } if (!is_object($this->Discussion)) { $this->EventArguments['DiscussionID'] = $DiscussionID; $this->fireEvent('DiscussionNotFound'); throw notFoundException('Discussion'); } // Define the query offset & limit. $Limit = c('Vanilla.Comments.PerPage', 30); $OffsetProvided = $Page != ''; list($Offset, $Limit) = offsetLimit($Page, $Limit); // Check permissions $this->permission('Vanilla.Discussions.View', true, 'Category', $this->Discussion->PermissionCategoryID); $this->setData('CategoryID', $this->CategoryID = $this->Discussion->CategoryID, true); if (strcasecmp(val('Type', $this->Discussion), 'redirect') === 0) { $this->redirectDiscussion($this->Discussion); } $Category = CategoryModel::categories($this->Discussion->CategoryID); $this->setData('Category', $Category); if ($CategoryCssClass = val('CssClass', $Category)) { Gdn_Theme::section($CategoryCssClass); } $this->setData('Breadcrumbs', CategoryModel::getAncestors($this->CategoryID)); // Setup $this->title($this->Discussion->Name); // Actual number of comments, excluding the discussion itself. $ActualResponses = $this->Discussion->CountComments; $this->Offset = $Offset; if (c('Vanilla.Comments.AutoOffset')) { // if ($this->Discussion->CountCommentWatch > 1 && $OffsetProvided == '') // $this->addDefinition('ScrollTo', 'a[name=Item_'.$this->Discussion->CountCommentWatch.']'); if (!is_numeric($this->Offset) || $this->Offset < 0 || !$OffsetProvided) { // Round down to the appropriate offset based on the user's read comments & comments per page $CountCommentWatch = $this->Discussion->CountCommentWatch > 0 ? $this->Discussion->CountCommentWatch : 0; if ($CountCommentWatch > $ActualResponses) { $CountCommentWatch = $ActualResponses; } // (((67 comments / 10 perpage) = 6.7) rounded down = 6) * 10 perpage = offset 60; $this->Offset = floor($CountCommentWatch / $Limit) * $Limit; } 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; } $LatestItem = $this->Discussion->CountCommentWatch; if ($LatestItem === null) { $LatestItem = 0; } elseif ($LatestItem < $this->Discussion->CountComments) { $LatestItem += 1; } $this->setData('_LatestItem', $LatestItem); // Set the canonical url to have the proper page title. $this->canonicalUrl(discussionUrl($this->Discussion, pageNumber($this->Offset, $Limit, 0, false))); // url(ConcatSep('/', 'discussion/'.$this->Discussion->DiscussionID.'/'. Gdn_Format::url($this->Discussion->Name), PageNumber($this->Offset, $Limit, TRUE, Gdn::session()->UserID != 0)), true), Gdn::session()->UserID == 0); // Load the comments $this->setData('Comments', $this->CommentModel->get($DiscussionID, $Limit, $this->Offset)); $PageNumber = PageNumber($this->Offset, $Limit); $this->setData('Page', $PageNumber); $this->_SetOpenGraph(); include_once PATH_LIBRARY . '/vendors/simplehtmldom/simple_html_dom.php'; if ($PageNumber == 1) { $this->description(sliceParagraph(Gdn_Format::plainText($this->Discussion->Body, $this->Discussion->Format), 160)); // Add images to head for open graph $Dom = str_get_html(Gdn_Format::to($this->Discussion->Body, $this->Discussion->Format)); } else { $this->Data['Title'] .= sprintf(t(' - Page %s'), PageNumber($this->Offset, $Limit)); $FirstComment = $this->data('Comments')->firstRow(); $FirstBody = val('Body', $FirstComment); $FirstFormat = val('Format', $FirstComment); $this->description(sliceParagraph(Gdn_Format::plainText($FirstBody, $FirstFormat), 160)); // Add images to head for open graph $Dom = str_get_html(Gdn_Format::to($FirstBody, $FirstFormat)); } if ($Dom) { foreach ($Dom->find('img') as $img) { if (isset($img->src)) { $this->image($img->src); } } } // Queue notification. if ($this->Request->get('new') && c('Vanilla.QueueNotifications')) { $this->addDefinition('NotifyNewDiscussion', 1); } // Make sure to set the user's discussion watch records if this is not an API request. if ($this->deliveryType() !== DELIVERY_TYPE_DATA) { $this->CommentModel->SetWatch($this->Discussion, $Limit, $this->Offset, $this->Discussion->CountComments); } // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->EventArguments['PagerType'] = 'Pager'; $this->fireEvent('BeforeBuildPager'); $this->Pager = $PagerFactory->getPager($this->EventArguments['PagerType'], $this); $this->Pager->ClientID = 'Pager'; $this->Pager->configure($this->Offset, $Limit, $ActualResponses, array('DiscussionUrl')); $this->Pager->Record = $this->Discussion; PagerModule::current($this->Pager); $this->fireEvent('AfterBuildPager'); // Define the form for the comment input $this->Form = Gdn::Factory('Form', 'Comment'); $this->Form->Action = url('/post/comment/'); $this->DiscussionID = $this->Discussion->DiscussionID; $this->Form->addHidden('DiscussionID', $this->DiscussionID); $this->Form->addHidden('CommentID', ''); // Look in the session stash for a comment $StashComment = $Session->getPublicStash('CommentForDiscussionID_' . $this->Discussion->DiscussionID); if ($StashComment) { $this->Form->setValue('Body', $StashComment); $this->Form->setFormValue('Body', $StashComment); } // Retrieve & apply the draft if there is one: if (Gdn::session()->UserID) { $DraftModel = new DraftModel(); $Draft = $DraftModel->get($Session->UserID, 0, 1, $this->Discussion->DiscussionID)->firstRow(); $this->Form->addHidden('DraftID', $Draft ? $Draft->DraftID : ''); if ($Draft && !$this->Form->isPostBack()) { $this->Form->setValue('Body', $Draft->Body); $this->Form->setValue('Format', $Draft->Format); } } // Deliver JSON data if necessary if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->setJson('LessRow', $this->Pager->toString('less')); $this->setJson('MoreRow', $this->Pager->toString('more')); $this->View = 'comments'; } // Inform moderator of checked comments in this discussion $CheckedComments = $Session->getAttribute('CheckedComments', array()); if (count($CheckedComments) > 0) { ModerationController::informCheckedComments($this); } // Add modules $this->addModule('DiscussionFilterModule'); $this->addModule('NewDiscussionModule'); $this->addModule('CategoriesModule'); $this->addModule('BookmarkedModule'); $this->CanEditComments = Gdn::session()->checkPermission('Vanilla.Comments.Edit', true, 'Category', 'any') && c('Vanilla.AdminCheckboxes.Use'); // Report the discussion id so js can use it. $this->addDefinition('DiscussionID', $DiscussionID); $this->addDefinition('Category', $this->data('Category.Name')); $this->fireEvent('BeforeDiscussionRender'); $AttachmentModel = AttachmentModel::instance(); if (AttachmentModel::enabled()) { $AttachmentModel->joinAttachments($this->Data['Discussion'], $this->Data['Comments']); $this->fireEvent('FetchAttachmentViews'); if ($this->deliveryMethod() === DELIVERY_METHOD_XHTML) { require_once $this->fetchViewLocation('attachment', 'attachments', 'dashboard'); } } $this->render(); }
/** * Renders a plaintext email. * * @return string A plaintext email. */ protected function plainTextEmail() { $email = ['banner' => val('alt', $this->image) . ' ' . val('link', $this->image), 'title' => $this->getTitle(), 'lead' => $this->getLead(), 'message' => $this->getMessage(), 'button' => sprintf(t('%s: %s'), val('text', $this->button), val('url', $this->button)), 'footer' => $this->getFooter()]; foreach ($email as $key => $val) { if (!$val) { unset($email[$key]); } else { if ($key == 'message') { $email[$key] = "<br>{$val}<br>"; } } } return Gdn_Format::plainText(Gdn_Format::text(implode('<br>', $email), false)); }
/** * Default search functionality. * * @since 2.0.0 * @access public * @param int $Page Page number. */ public function index($Page = '') { $this->addJsFile('search.js'); $this->title(t('Search')); saveToConfig('Garden.Format.EmbedSize', '160x90', false); Gdn_Theme::section('SearchResults'); list($Offset, $Limit) = offsetLimit($Page, c('Garden.Search.PerPage', 20)); $this->setData('_Limit', $Limit); $Search = $this->Form->getFormValue('Search'); $Mode = $this->Form->getFormValue('Mode'); if ($Mode) { $this->SearchModel->ForceSearchMode = $Mode; } try { $ResultSet = $this->SearchModel->Search($Search, $Offset, $Limit); } catch (Gdn_UserException $Ex) { $this->Form->addError($Ex); $ResultSet = array(); } catch (Exception $Ex) { LogException($Ex); $this->Form->addError($Ex); $ResultSet = array(); } Gdn::userModel()->joinUsers($ResultSet, array('UserID')); // Fix up the summaries. $SearchTerms = explode(' ', Gdn_Format::text($Search)); foreach ($ResultSet as &$Row) { $Row['Summary'] = SearchExcerpt(Gdn_Format::plainText($Row['Summary'], $Row['Format']), $SearchTerms); $Row['Summary'] = Emoji::instance()->translateToHtml($Row['Summary']); $Row['Format'] = 'Html'; } $this->setData('SearchResults', $ResultSet, true); $this->setData('SearchTerm', Gdn_Format::text($Search), true); if ($ResultSet) { $NumResults = count($ResultSet); } else { $NumResults = 0; } if ($NumResults == $Offset + $Limit) { $NumResults++; } // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->Pager = $PagerFactory->GetPager('MorePager', $this); $this->Pager->MoreCode = 'More Results'; $this->Pager->LessCode = 'Previous Results'; $this->Pager->ClientID = 'Pager'; $this->Pager->configure($Offset, $Limit, $NumResults, 'dashboard/search/%1$s/%2$s/?Search=' . Gdn_Format::url($Search)); // if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { // $this->setJson('LessRow', $this->Pager->toString('less')); // $this->setJson('MoreRow', $this->Pager->toString('more')); // $this->View = 'results'; // } $this->canonicalUrl(url('search', true)); $this->render(); }
?> <li class="Item" rel="<?php echo url("/messages/{$Row['ConversationID']}#Message_{$Row['LastMessageID']}"); ?> "> <div class="Author Photo"><?php echo userPhoto($PhotoUser); ?> </div> <div class="ItemContent"> <b class="Subject"><?php echo anchor($Subject, "/messages/{$Row['ConversationID']}#Message_{$Row['LastMessageID']}"); ?> </b> <?php $Excerpt = sliceString(Gdn_Format::plainText($Row['LastBody'], $Row['LastFormat']), 80); echo wrap(nl2br(htmlspecialchars($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 }
/** * * * @param $Type * @param $ID * @param $QuoteData * @param bool $Format */ protected function formatQuote($Type, $ID, &$QuoteData, $Format = false) { // Temporarily disable Emoji parsing (prevent double-parsing to HTML) $emojiEnabled = Emoji::instance()->enabled; Emoji::instance()->enabled = false; if (!$Format) { $Format = c('Garden.InputFormatter'); } $Type = strtolower($Type); $Model = false; switch ($Type) { case 'comment': $Model = new CommentModel(); break; case 'discussion': $Model = new DiscussionModel(); break; default: break; } //$QuoteData = array(); if ($Model) { $Data = $Model->getID($ID); $NewFormat = $Format; if ($NewFormat == 'Wysiwyg') { $NewFormat = 'Html'; } $QuoteFormat = $Data->Format; if ($QuoteFormat == 'Wysiwyg') { $QuoteFormat = 'Html'; } // Perform transcoding if possible $NewBody = $Data->Body; if ($QuoteFormat != $NewFormat) { if (in_array($NewFormat, array('Html', 'Wysiwyg'))) { $NewBody = Gdn_Format::to($NewBody, $QuoteFormat); } elseif ($QuoteFormat == 'Html' && $NewFormat == 'BBCode') { $NewBody = Gdn_Format::text($NewBody, false); } elseif ($QuoteFormat == 'Text' && $NewFormat == 'BBCode') { $NewBody = Gdn_Format::text($NewBody, false); } else { $NewBody = Gdn_Format::plainText($NewBody, $QuoteFormat); } if (!in_array($NewFormat, array('Html', 'Wysiwyg'))) { Gdn::controller()->informMessage(sprintf(t('The quote had to be converted from %s to %s.', 'The quote had to be converted from %s to %s. Some formatting may have been lost.'), htmlspecialchars($QuoteFormat), htmlspecialchars($NewFormat))); } } $Data->Body = $NewBody; // Format the quote according to the format. switch ($Format) { case 'Html': // HTML $Quote = '<blockquote class="Quote" rel="' . htmlspecialchars($Data->InsertName) . '">' . $Data->Body . '</blockquote>' . "\n"; break; case 'BBCode': $Author = htmlspecialchars($Data->InsertName); if ($ID) { $IDString = ';' . htmlspecialchars($ID); } $QuoteBody = $Data->Body; // TODO: Strip inner quotes... // $QuoteBody = trim(preg_replace('`(\[quote.*/quote\])`si', '', $QuoteBody)); $Quote = <<<BQ [quote="{$Author}{$IDString}"]{$QuoteBody}[/quote] BQ; break; case 'Markdown': case 'Display': case 'Text': $QuoteBody = $Data->Body; // Strip inner quotes and mentions... $QuoteBody = self::_stripMarkdownQuotes($QuoteBody); $QuoteBody = self::_stripMentions($QuoteBody); $Quote = '> ' . sprintf(t('%s said:'), '@' . $Data->InsertName) . "\n" . '> ' . str_replace("\n", "\n> ", $QuoteBody) . "\n"; break; case 'Wysiwyg': $Attribution = sprintf(t('%s said:'), userAnchor($Data, null, array('Px' => 'Insert'))); $QuoteBody = $Data->Body; // TODO: Strip inner quotes... // $QuoteBody = trim(preg_replace('`(<blockquote.*/blockquote>)`si', '', $QuoteBody)); $Quote = <<<BLOCKQUOTE <blockquote class="Quote"> <div class="QuoteAuthor">{$Attribution}</div> <div class="QuoteText">{$QuoteBody}</div> </blockquote> BLOCKQUOTE; break; } $QuoteData = array_merge($QuoteData, array('status' => 'success', 'body' => $Quote, 'format' => $Format, 'authorid' => $Data->InsertUserID, 'authorname' => $Data->InsertName, 'type' => $Type, 'typeid' => $ID)); } // Undo Emoji disable. Emoji::instance()->enabled = $emojiEnabled; }
/** * * @param PostController $Sender * @param type $RecordType * @param type $ID * @throws type */ public function postController_facebook_create($Sender, $RecordType, $ID) { if (!$this->socialReactions()) { throw permissionException(); } $Row = getRecord($RecordType, $ID, true); if ($Row) { $Message = sliceParagraph(Gdn_Format::plainText($Row['Body'], $Row['Format']), 160); if ($this->accessToken() && $Sender->Request->isPostBack()) { $R = $this->api('/me/feed', array('link' => $Row['ShareUrl'], 'message' => $Message)); $Sender->setJson('R', $R); $Sender->informMessage(t('Thanks for sharing!')); } else { $Get = array('app_id' => c('Plugins.Facebook.ApplicationID'), 'link' => $Row['ShareUrl'], 'name' => Gdn_Format::plainText($Row['Name'], 'Text'), 'description' => $Message, 'redirect_uri' => url('/post/shared/facebook', true)); $Url = 'http://www.facebook.com/dialog/feed?' . http_build_query($Get); redirect($Url); } } $Sender->render('Blank', 'Utility', 'Dashboard'); }
/** * Renders a plaintext email. * * @return string A plaintext email. */ protected function plainTextEmail() { return Gdn_Format::plainText(Gdn_Format::text($this->getMessage())); }
$LastPhoto = userPhoto($User); if ($LastPhoto) { 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; $Message = sliceString(Gdn_Format::plainText($Conversation->LastBody, $Conversation->LastFormat), 100); if (stringIsNullOrEmpty(trim($Message))) { $Message = t('Blank Message'); } $this->EventArguments['Conversation'] = $Conversation; ?> <li class="<?php echo $CssClass; ?> "> <?php $Names = ConversationModel::participantTitle($Conversation, false); ?> <div class="ItemContent Conversation"> <?php $Url = '/messages/' . $Conversation->ConversationID . '/#Item_' . $JumpToItem;
/** * Queue a notification for sending. * * @since 2.0.17 * @access public * @param int $ActivityID * @param string $Story * @param string $Position * @param bool $Force */ public function queueNotification($ActivityID, $Story = '', $Position = 'last', $Force = false) { $Activity = $this->getID($ActivityID); if (!is_object($Activity)) { return; } $Story = Gdn_Format::text($Story == '' ? $Activity->Story : $Story, false); // If this is a comment on another activity, fudge the activity a bit so that everything appears properly. if (is_null($Activity->RegardingUserID) && $Activity->CommentActivityID > 0) { $CommentActivity = $this->getID($Activity->CommentActivityID); $Activity->RegardingUserID = $CommentActivity->RegardingUserID; $Activity->Route = '/activity/item/' . $Activity->CommentActivityID; } $User = Gdn::userModel()->getID($Activity->RegardingUserID, DATASET_TYPE_OBJECT); //$this->SQL->select('UserID, Name, Email, Preferences')->from('User')->where('UserID', $Activity->RegardingUserID)->get()->firstRow(); if ($User) { if ($Force) { $Preference = $Force; } else { // $Preferences = Gdn_Format::Unserialize($User->Preferences); $ConfigPreference = c('Preferences.Email.' . $Activity->ActivityType, '0'); if ($ConfigPreference !== false) { $Preference = val('Email.' . $Activity->ActivityType, $User->Preferences, $ConfigPreference); } else { $Preference = false; } } if ($Preference) { $ActivityHeadline = Gdn_Format::text(Gdn_Format::activityHeadline($Activity, $Activity->ActivityUserID, $Activity->RegardingUserID), false); $Email = new Gdn_Email(); $Email->subject(sprintf(t('[%1$s] %2$s'), Gdn::config('Garden.Title'), $ActivityHeadline)); $Email->to($User); $url = externalUrl(val('Route', $Activity) == '' ? '/' : val('Route', $Activity)); $emailTemplate = $Email->getEmailTemplate()->setButton($url, t('Check it out'))->setTitle(Gdn_Format::plainText(val('Headline', $Activity))); if ($message = val('Story', $Activity)) { $emailTemplate->setMessage($message, true); } $Email->setEmailTemplate($emailTemplate); if (!array_key_exists($User->UserID, $this->_NotificationQueue)) { $this->_NotificationQueue[$User->UserID] = array(); } $Notification = array('ActivityID' => $ActivityID, 'User' => $User, 'Email' => $Email, 'Route' => $Activity->Route, 'Story' => $Story, 'Headline' => $ActivityHeadline, 'Activity' => $Activity); if ($Position == 'first') { $this->_NotificationQueue[$User->UserID] = array_merge(array($Notification), $this->_NotificationQueue[$User->UserID]); } else { $this->_NotificationQueue[$User->UserID][] = $Notification; } } } }
/** * * * @param $Activity * @param bool $NoDelete * @return bool * @throws Exception */ public function email(&$Activity, $NoDelete = false) { if (is_numeric($Activity)) { $ActivityID = $Activity; $Activity = $this->getID($ActivityID); } else { $ActivityID = val('ActivityID', $Activity); } if (!$Activity) { return false; } $Activity = (array) $Activity; $User = Gdn::userModel()->getID($Activity['NotifyUserID'], DATASET_TYPE_ARRAY); if (!$User) { return false; } // Format the activity headline based on the user being emailed. if (val('HeadlineFormat', $Activity)) { $SessionUserID = Gdn::session()->UserID; Gdn::session()->UserID = $User['UserID']; $Activity['Headline'] = formatString($Activity['HeadlineFormat'], $Activity); Gdn::session()->UserID = $SessionUserID; } else { if (!isset($Activity['ActivityGender'])) { $AT = self::getActivityType($Activity['ActivityType']); $Data = array($Activity); self::joinUsers($Data); $Activity = $Data[0]; $Activity['RouteCode'] = val('RouteCode', $AT); $Activity['FullHeadline'] = val('FullHeadline', $AT); $Activity['ProfileHeadline'] = val('ProfileHeadline', $AT); } $Activity['Headline'] = Gdn_Format::activityHeadline($Activity, '', $User['UserID']); } // Build the email to send. $Email = new Gdn_Email(); $Email->subject(sprintf(t('[%1$s] %2$s'), c('Garden.Title'), Gdn_Format::plainText($Activity['Headline']))); $Email->to($User); $Url = ExternalUrl($Activity['Route'] == '' ? '/' : $Activity['Route']); if ($Activity['Story']) { $Message = sprintf(t('EmailStoryNotification', "%3\$s\n\n%2\$s"), Gdn_Format::plainText($Activity['Headline']), $Url, Gdn_Format::plainText($Activity['Story'])); } else { $Message = sprintf(t('EmailNotification', "%1\$s\n\n%2\$s"), Gdn_Format::plainText($Activity['Headline']), $Url); } $Email->message($Message); // Fire an event for the notification. $Notification = array('ActivityID' => $ActivityID, 'User' => $User, 'Email' => $Email, 'Route' => $Activity['Route'], 'Story' => $Activity['Story'], 'Headline' => $Activity['Headline'], 'Activity' => $Activity); $this->EventArguments = $Notification; $this->fireEvent('BeforeSendNotification'); // Send the email. try { // Only send if the user is not banned if (!val('Banned', $User)) { $Email->send(); } $Emailed = self::SENT_OK; // Delete the activity now that it has been emailed. if (!$NoDelete && !$Activity['Notified']) { if (val('ActivityID', $Activity)) { $this->delete($Activity['ActivityID']); } else { $Activity['_Delete'] = true; } } } catch (phpmailerException $pex) { if ($pex->getCode() == PHPMailer::STOP_CRITICAL) { $Emailed = self::SENT_FAIL; } else { $Emailed = self::SENT_ERROR; } } catch (Exception $ex) { $Emailed = self::SENT_FAIL; // similar to http 5xx } $Activity['Emailed'] = $Emailed; if ($ActivityID) { // Save the emailed flag back to the activity. $this->SQL->put('Activity', array('Emailed' => $Emailed), array('ActivityID' => $ActivityID)); } }
/** * * * @param bool $Value * @param bool $PlainText * @return mixed */ public function description($Value = false, $PlainText = false) { if ($Value != false) { if ($PlainText) { $Value = Gdn_Format::plainText($Value); } $this->setData('_Description', $Value); } return $this->data('_Description'); }
/** * * * @param bool $Notify * @param bool $UserID */ public function post($Notify = false, $UserID = false) { if (is_numeric($Notify)) { $UserID = $Notify; $Notify = false; } if (!$UserID) { $UserID = Gdn::session()->UserID; } switch ($Notify) { case 'mods': $this->permission('Garden.Moderation.Manage'); $NotifyUserID = ActivityModel::NOTIFY_MODS; break; case 'admins': $this->permission('Garden.Settings.Manage'); $NotifyUserID = ActivityModel::NOTIFY_ADMINS; break; default: $this->permission('Garden.Profiles.Edit'); $NotifyUserID = ActivityModel::NOTIFY_PUBLIC; break; } $Activities = array(); if ($this->Form->authenticatedPostBack()) { $Data = $this->Form->formValues(); $Data = $this->ActivityModel->filterForm($Data); if (!isset($Data['Format']) || strcasecmp($Data['Format'], 'Raw') == 0) { $Data['Format'] = c('Garden.InputFormatter'); } if ($UserID != Gdn::session()->UserID) { // This is a wall post. $Activity = array('ActivityType' => 'WallPost', 'ActivityUserID' => $UserID, 'RegardingUserID' => Gdn::session()->UserID, 'HeadlineFormat' => t('HeadlineFormat.WallPost', '{RegardingUserID,you} → {ActivityUserID,you}'), 'Story' => $Data['Comment'], 'Format' => $Data['Format'], 'Data' => array('Bump' => true)); } else { // This is a status update. $Activity = array('ActivityType' => 'Status', 'HeadlineFormat' => t('HeadlineFormat.Status', '{ActivityUserID,user}'), 'Story' => $Data['Comment'], 'Format' => $Data['Format'], 'NotifyUserID' => $NotifyUserID, 'Data' => array('Bump' => true)); $this->setJson('StatusMessage', Gdn_Format::plainText($Activity['Story'], $Activity['Format'])); } $Activity = $this->ActivityModel->save($Activity, false, array('CheckSpam' => true)); if ($Activity == SPAM || $Activity == UNAPPROVED) { $this->StatusMessage = t('ActivityRequiresApproval', 'Your post will appear after it is approved.'); $this->render('Blank', 'Utility'); return; } if ($Activity) { if ($UserID == Gdn::session()->UserID && $NotifyUserID == ActivityModel::NOTIFY_PUBLIC) { Gdn::userModel()->setField(Gdn::session()->UserID, 'About', Gdn_Format::plainText($Activity['Story'], $Activity['Format'])); } $Activities = array($Activity); ActivityModel::joinUsers($Activities); $this->ActivityModel->calculateData($Activities); } else { $this->Form->setValidationResults($this->ActivityModel->validationResults()); $this->StatusMessage = $this->ActivityModel->Validation->resultsText(); // $this->render('Blank', 'Utility'); } } if ($this->deliveryType() == DELIVERY_TYPE_ALL) { $Target = $this->Request->get('Target', '/activity'); if (isSafeUrl($Target)) { redirect($Target); } else { redirect(url('/activity')); } } $this->setData('Activities', $Activities); $this->render('Activities'); }
/** * Default search functionality. * * @since 2.0.0 * @access public * @param int $Page Page number. */ public function index($Page = '') { $this->addJsFile('search.js'); $this->title(t('Search')); saveToConfig('Garden.Format.EmbedSize', '160x90', false); Gdn_Theme::section('SearchResults'); list($Offset, $Limit) = offsetLimit($Page, c('Garden.Search.PerPage', 20)); $this->setData('_Limit', $Limit); $Search = $this->Form->getFormValue('Search'); $Mode = $this->Form->getFormValue('Mode'); if ($Mode) { $this->SearchModel->ForceSearchMode = $Mode; } try { $ResultSet = $this->SearchModel->search($Search, $Offset, $Limit); } catch (Gdn_UserException $Ex) { $this->Form->addError($Ex); $ResultSet = array(); } catch (Exception $Ex) { LogException($Ex); $this->Form->addError($Ex); $ResultSet = array(); } Gdn::userModel()->joinUsers($ResultSet, array('UserID')); // Fix up the summaries. $SearchTerms = explode(' ', Gdn_Format::text($Search)); foreach ($ResultSet as &$Row) { $Row['Summary'] = searchExcerpt(htmlspecialchars(Gdn_Format::plainText($Row['Summary'], $Row['Format'])), $SearchTerms); $Row['Summary'] = Emoji::instance()->translateToHtml($Row['Summary']); $Row['Format'] = 'Html'; } $this->setData('SearchResults', $ResultSet, true); $this->setData('SearchTerm', Gdn_Format::text($Search), true); $this->setData('_CurrentRecords', count($ResultSet)); $this->canonicalUrl(url('search', true)); $this->render(); }
/** * * * @param PostController $Sender * @param type $RecordType * @param type $ID * @throws type */ public function postController_googlePlus_create($Sender, $RecordType, $ID) { $Row = GetRecord($RecordType, $ID); if ($Row) { $Message = SliceParagraph(Gdn_Format::plainText($Row['Body'], $Row['Format']), 160); $Get = array('url' => $Row['ShareUrl']); $Url = 'https://plus.google.com/share?' . http_build_query($Get); redirect($Url); } $Sender->render('Blank', 'Utility', 'Dashboard'); }
/** * Format a serialized string of image properties as html. * @param string $Body a serialized array of image properties (Image, Thumbnail, Caption) */ public static function image($Body) { if (is_string($Body)) { $Image = @unserialize($Body); if (!$Image) { return Gdn_Format::html($Body); } } $Url = GetValue('Image', $Image); $Caption = Gdn_Format::plainText(val('Caption', $Image)); return '<div class="ImageWrap">' . '<div class="Image">' . Img($Url, array('alt' => $Caption, 'title' => $Caption)) . '</div>' . '<div class="Caption">' . $Caption . '</div>' . '</div>'; }
/** * Write a promoted content item in a table or modern view. * * @param array $row The row to output. * @param string $view The view to use. */ function writePromotedContentRow($row, $view) { $title = htmlspecialchars(val('Name', $row)); $url = val('Url', $row); $body = Gdn_Format::plainText(val('Body', $row), val('Format', $row)); $categoryUrl = val('CategoryUrl', $row); $categoryName = val('CategoryName', $row); $date = val('DateUpdated', $row) ?: val('DateInserted', $row); $date = Gdn_Format::date($date, 'html'); $type = val('RecordType', $row, 'post'); $id = val('CommentID', $row, val('DiscussionID', $row, '')); $author = val('Author', $row); $username = val('Name', $author); $userUrl = val('Url', $author); $userPhoto = val('PhotoUrl', $author); $cssClass = val('CssClass', $author); if ($view == 'table') { ?> <tr id="Promoted_<?php echo $type . '_' . $id; ?> " class="Item PromotedContent-Item <?php echo $cssClass; ?> "> <td class="Name"> <div class="Wrap"> <a class="Title" href="<?php echo $url; ?> "> <?php echo $title; ?> </a> <span class="MItem Category"><?php echo t('in'); ?> <a href="<?php echo $categoryUrl; ?> " class="MItem-CategoryName"><?php echo $categoryName; ?> </a></span> <div class="Description"><?php echo $body; ?> </div> </div> </td> <td class="BlockColumn BlockColumn-User User"> <div class="Block Wrap"> <a class="PhotoWrap PhotoWrapSmall" href="<?php echo $userUrl; ?> "> <img class="ProfilePhoto ProfilePhotoSmall" src="<?php echo $userPhoto; ?> "> </a> <a class="UserLink BlockTitle" href="<?php echo $userUrl; ?> "><?php echo $username; ?> </a> <div class="Meta"> <a class="CommentDate MItem" href="<?php echo $url; ?> "><?php echo $date; ?> </a> </div> </div> </td> </tr> <?php } else { ?> <li id="Promoted_<?php echo $type . '_' . $id; ?> " class="Item PromotedContent-Item <?php echo $cssClass; ?> "> <?php if (c('EnabledPlugins.IndexPhotos')) { ?> <a title="<?php echo $username; ?> " href="<?php echo $userUrl; ?> " class="IndexPhoto PhotoWrap"> <img src="<?php echo $userPhoto; ?> " alt="<?php echo $username; ?> " class="ProfilePhoto ProfilePhotoMedium"> </a> <?php } ?> <div class="ItemContent Discussion"> <div class="Title"> <a href="<?php echo $url; ?> "> <?php echo $title; ?> </a> </div> <div class="Excerpt"><?php echo $body; ?> </div> <div class="Meta"> <span class="MItem DiscussionAuthor"><ahref="<?php echo $userUrl; ?> "><?php echo $username; ?> </a></span> <span class="MItem Category"><?php echo t('in'); ?> <a href="<?php echo $categoryUrl; ?> " class="MItem-CategoryName"><?php echo $categoryName; ?> </a></span> </div> </div> </li> <?php } }
} foreach ($this->data('Comments') as $Comment) { $Permalink = '/discussion/comment/' . $Comment->CommentID . '/#Comment_' . $Comment->CommentID; $User = UserBuilder($Comment, 'Insert'); $this->EventArguments['User'] = $User; ?> <li id="<?php echo 'Comment_' . $Comment->CommentID; ?> " class="Item"> <?php $this->fireEvent('BeforeItemContent'); ?> <div class="ItemContent"> <div class="Message"><?php echo SliceString(Gdn_Format::plainText($Comment->Body, $Comment->Format), 250); ?> </div> <div class="Meta"> <span class="MItem"><?php echo t('Comment in', 'in') . ' '; ?> <b><?php echo anchor(Gdn_Format::text($Comment->DiscussionName), $Permalink); ?> </b></span> <span class="MItem"><?php printf(t('Comment by %s'), userAnchor($User)); ?> </span> <span class="MItem"><?php