protected function _CacheOnlineUserss(&$Sender) { //logic taken from Who's Online plugin $SQL = Gdn::SQL(); // $this->_OnlineUsers = $SQL // insert or update entry into table $Session = Gdn::Session(); $Invisible = $Invisible ? 1 : 0; if ($Session->UserID) { $SQL->Replace('Whosonline', array('UserID' => $Session->UserID, 'Timestamp' => Gdn_Format::ToDateTime(), 'Invisible' => $Invisible), array('UserID' => $Session->UserID)); } $Frequency = C('WhosOnline.Frequency', 4); $History = time() - $Frequency; $SQL->Select('u.UserID, u.Name, w.Timestamp, w.Invisible')->From('Whosonline w')->Join('User u', 'w.UserID = u.UserID')->Where('w.Timestamp >=', date('Y-m-d H:i:s', $History))->OrderBy('u.Name'); if (!$Session->CheckPermission('Plugins.WhosOnline.ViewHidden')) { $SQL->Where('w.Invisible', 0); } $OnlineUsers = $SQL->Get(); $arrOnline = array(); if ($OnlineUsers->NumRows() > 0) { foreach ($OnlineUsers->Result() as $User) { $arrOnline[] = $User->UserID; } } $Sender->SetData('Plugin-OnlineUsers-Marker', $arrOnline); }
/** * 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')); } }
public function Index($Offset = 0, $Limit = NULL) { $this->AddJsFile('/js/library/jquery.gardenmorepager.js'); $this->AddJsFile('search.js'); $this->Title(T('Search')); if (!is_numeric($Limit)) { $Limit = Gdn::Config('Garden.Search.PerPage', 20); } $Search = $this->Form->GetFormValue('Search'); $ResultSet = $this->SearchModel->Search($Search, $Offset, $Limit); $this->SetData('SearchResults', $ResultSet, TRUE); $this->SetData('SearchTerm', Gdn_Format::Text($Search), TRUE); if ($ResultSet) { $NumResults = $ResultSet->NumRows(); } else { $NumResults = 0; } if ($NumResults == $Offset + $Limit) { $NumResults++; } // Build a pager $PagerFactory = new Gdn_PagerFactory(); $Pager = $PagerFactory->GetPager('MorePager', $this); $Pager->MoreCode = 'More Results'; $Pager->LessCode = 'Previous Results'; $Pager->ClientID = 'Pager'; $Pager->Configure($Offset, $Limit, $NumResults, 'dashboard/search/%1$s/%2$s/?Search=' . Gdn_Format::Url($Search)); $this->SetData('Pager', $Pager, TRUE); if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->SetJson('LessRow', $this->Pager->ToString('less')); $this->SetJson('MoreRow', $this->Pager->ToString('more')); $this->View = 'results'; } $this->Render(); }
public function ToString() { if ($this->_UserData->NumRows() == 0) { return ''; } $String = ''; ob_start(); ?> <div class="Box"> <?php echo panelHeading(T('In this Discussion')); ?> <ul class="PanelInfo"> <?php foreach ($this->_UserData->Result() as $User) { ?> <li> <?php echo Anchor(Wrap(Wrap(Gdn_Format::Date($User->DateLastActive, 'html')), 'span', array('class' => 'Aside')) . ' ' . Wrap(Wrap(GetValue('Name', $User), 'span', array('class' => 'Username')), 'span'), UserUrl($User)); ?> </li> <?php } ?> </ul> </div> <?php $String = ob_get_contents(); @ob_end_clean(); return $String; }
/** * * * @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); }
function WriteDiscussion($Discussion, &$Sender, &$Session, $Alt) { $CssClass = 'Item'; $CssClass .= $Discussion->Bookmarked == '1' ? ' Bookmarked' : ''; $CssClass .= $Alt . ' '; $CssClass .= $Discussion->Announce == '1' ? ' Announcement' : ''; $CssClass .= $Discussion->Closed == '1' ? ' Closed' : ''; $CssClass .= $Discussion->InsertUserID == $Session->UserID ? ' Mine' : ''; $CssClass .= $Discussion->CountUnreadComments > 0 && $Session->IsValid() ? ' New' : ''; $Sender->EventArguments['Discussion'] =& $Discussion; $Sender->FireEvent('BeforeDiscussionName'); $DiscussionName = Gdn_Format::Text($Discussion->Name); if ($DiscussionName == '') { $DiscussionName = T('Blank Discussion Topic'); } static $FirstDiscussion = TRUE; if (!$FirstDiscussion) { $Sender->FireEvent('BetweenDiscussion'); } else { $FirstDiscussion = FALSE; } ?> <li class="<?php echo $CssClass; ?> "> <?php if ($Discussion->FirstPhoto != '') { if (strtolower(substr($Discussion->FirstPhoto, 0, 7)) == 'http://' || strtolower(substr($Discussion->FirstPhoto, 0, 8)) == 'https://') { $PhotoUrl = $Discussion->FirstPhoto; } else { $PhotoUrl = 'uploads/' . ChangeBasename($Discussion->FirstPhoto, 'n%s'); } echo Img($PhotoUrl, array('alt' => $Discussion->FirstName)); } ?> <div class="ItemContent Discussion"> <?php echo Anchor($DiscussionName, '/discussion/' . $Discussion->DiscussionID . '/' . Gdn_Format::Url($Discussion->Name) . ($Discussion->CountCommentWatch > 0 && C('Vanilla.Comments.AutoOffset') ? '/#Item_' . $Discussion->CountCommentWatch : ''), 'Title'); ?> <?php $Sender->FireEvent('AfterDiscussionTitle'); ?> <div class="Meta"> <span class="Author"><?php echo $Discussion->FirstName; ?> </span> <?php echo '<span class="Counts' . ($Discussion->CountUnreadComments > 0 ? ' NewCounts' : '') . '">' . ($Discussion->CountUnreadComments > 0 ? $Discussion->CountUnreadComments . '/' : '') . $Discussion->CountComments . '</span>'; if ($Discussion->LastCommentID != '') { echo '<span class="LastCommentBy">' . sprintf(T('Latest %1$s'), $Discussion->LastName) . '</span> '; } echo '<span class="LastCommentDate">' . Gdn_Format::Date($Discussion->FirstDate) . '</span> '; ?> </div> </div> </li> <?php }
/** * * * @param $Data */ function _checkTable($Data) { echo "<table class='Data' width='100%' style='table-layout: fixed;'>\n"; echo "<thead><tr><td width='20%'>Field</td><td width='45%'>Current</td><td width='35%'>File</td></tr></thead>"; $First = true; foreach ($Data as $Key => $Value) { if (stringBeginsWith($Key, 'File_') || is_array($Value) || $Key == 'Name') { continue; } $Value = Gdn_Format::html($Value); $FileValue = Gdn_Format::html(val('File_' . $Key, $Data)); if ($Key == 'MD5') { $Value = substr($Value, 0, 10); $FileValue = substr($FileValue, 0, 10); } if ($Key == 'FileSize') { $Value = Gdn_Upload::FormatFileSize($Value); } echo "<tr><td>{$Key}</td><td>{$Value}</td>"; if ($Error = val('File_Error', $Data)) { if ($First) { echo '<td rowspan="4">', htmlspecialchars($Error), '</td>'; } } else { echo "<td>{$FileValue}</td></tr>"; } echo "\n"; $First = false; } echo '</table>'; }
/** * Build HTML. * * @return string HTML. */ public function toString() { if ($this->_UserData->numRows() == 0) { return ''; } $String = ''; ob_start(); ?> <div class="Box BoxInThisDiscussion"> <?php echo panelHeading(t('In this Discussion')); ?> <ul class="PanelInfo PanelInThisDiscussion"> <?php foreach ($this->_UserData->Result() as $User) { ?> <li> <?php echo anchor(wrap(wrap(Gdn_Format::date($User->DateLastActive, 'html')), 'span', array('class' => 'Aside')) . ' ' . wrap(wrap(val('Name', $User), 'span', array('class' => 'Username')), 'span'), userUrl($User)); ?> </li> <?php } ?> </ul> </div> <?php $String = ob_get_clean(); return $String; }
/** * Award a badge to a user and record some activity * * @param int $BadgeID * @param int $UserID This is the user that should get the award * @param int $InsertUserID This is the user that gave the award * @param string $Reason This is the reason the giver gave with the award */ public function Award($BadgeID, $UserID, $InsertUserID = NULL, $Reason = '') { $Badge = Yaga::BadgeModel()->GetByID($BadgeID); if (!empty($Badge)) { if (!$this->Exists($UserID, $BadgeID)) { $this->SQL->Insert('BadgeAward', array('BadgeID' => $BadgeID, 'UserID' => $UserID, 'InsertUserID' => $InsertUserID, 'Reason' => $Reason, 'DateInserted' => date(DATE_ISO8601))); // Record the points for this badge UserModel::GivePoints($UserID, $Badge->AwardValue, 'Badge'); // Increment the user's badge count $this->SQL->Update('User')->Set('CountBadges', 'CountBadges + 1', FALSE)->Where('UserID', $UserID)->Put(); if (is_null($InsertUserID)) { $InsertUserID = Gdn::Session()->UserID; } // Record some activity $ActivityModel = new ActivityModel(); $Activity = array('ActivityType' => 'BadgeAward', 'ActivityUserID' => $UserID, 'RegardingUserID' => $InsertUserID, 'Photo' => $Badge->Photo, 'RecordType' => 'Badge', 'RecordID' => $BadgeID, 'Route' => '/badges/detail/' . $Badge->BadgeID . '/' . Gdn_Format::Url($Badge->Name), 'HeadlineFormat' => T('Yaga.Badge.EarnedHeadlineFormat'), 'Data' => array('Name' => $Badge->Name), 'Story' => $Badge->Description); // Create a public record $ActivityModel->Queue($Activity, FALSE); // TODO: enable the grouped notifications after issue #1776 is resolved , array('GroupBy' => 'Route')); // Notify the user of the award $Activity['NotifyUserID'] = $UserID; $ActivityModel->Queue($Activity, 'BadgeAward', array('Force' => TRUE)); // Actually save the activity $ActivityModel->SaveQueue(); $this->EventArguments['UserID'] = $UserID; $this->FireEvent('AfterBadgeAward'); } } }
/** * Resolves a discussion * * @param object $discussion * @param int $resolve * @return void */ public function resolve(&$discussion, $resolve) { $resolution = array('Resolved' => $resolve, 'DateResolved' => $resolve ? Gdn_Format::toDateTime() : null, 'ResolvedUserID' => $resolve ? Gdn::session()->UserID : null); $discussionID = val('DiscussionID', $discussion); self::discussionModel()->setField($discussionID, $resolution); svalr('Resolved', $discussion, $resolve); }
public function ToString() { $String = ''; ob_start(); ?> <div class="Box"> <h4><?php echo T('In this Discussion'); ?> </h4> <ul class="PanelInfo"> <?php foreach ($this->_UserData->Result() as $User) { ?> <li> <strong><?php echo UserAnchor($User, 'UserLink'); ?> </strong> <?php echo Gdn_Format::Date($User->DateLastActive); ?> </li> <?php } ?> </ul> </div> <?php $String = ob_get_contents(); @ob_end_clean(); return $String; }
/** * List download stats. * * @param bool|false $Offset */ public function index($Offset = false) { $this->permission('Garden.Settings.Manage'); $this->addSideMenu('vstats'); $this->addJsFile('jquery.gardenmorepager.js'); $this->title('Vanilla Stats'); $this->Form->Method = 'get'; $Offset = is_numeric($Offset) ? $Offset : 0; $Limit = 19; $this->StatsData = array(); $Offset--; $Year = date('Y'); $Month = date('m'); $BaseDate = Gdn_Format::toTimestamp($Year . '-' . str_pad($Month, 2, '0', STR_PAD_LEFT) . '-01 00:00:00'); for ($i = $Offset; $i <= $Limit; ++$i) { $String = "-{$i} month"; $this->StatsData[] = $this->_getStats(date("Y-m-d 00:00:00", strtotime($String, $BaseDate))); } $TotalRecords = count($this->StatsData); // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->Pager = $PagerFactory->getPager('MorePager', $this); $this->Pager->MoreCode = 'More'; $this->Pager->LessCode = 'Previous'; $this->Pager->ClientID = 'Pager'; $this->Pager->Wrapper = '<tr %1$s><td colspan="6">%2$s</td></tr>'; $this->Pager->configure($Offset, $Limit, $TotalRecords, 'vstats/index/%1$s/'); // 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->render(); }
/** * Checks the local Steam Profile cache for existing user profile * information. If found, serve it up. If not found, attempt to fetch * it from the Steam Community website. * * @param string $SteamID A sixty-four bit integer representing the target Steam ID * @return mixed SimpleXMLElement on success, FALSE on failure */ public function GetByID($SteamID) { // Verify that the ID is only digits and that we have SimpleXML capabilities if (preg_match('/\\d+/', $SteamID) && function_exists('simplexml_load_file')) { /** * Check to see if there are any cached profile records matching the ID and are * more than five minutes old */ $CachedProfile = $this->SQL->Select()->From('SteamProfileCache')->Where('SteamID64', $SteamID)->Where('DateRetrieved >', Gdn_Format::ToDateTime(strtotime('-5 minutes')))->Get()->Firstrow(); // Any cached entries? if ($CachedProfile) { // ...if so, load up the profile XML into a SimpleXMLElement... $CommunityProfile = simplexml_load_string($CachedProfile->ProfileXML, 'SimpleXMLElement', LIBXML_NOCDATA); // set the DateRetrieved of the cached record and go $CommunityProfile->DateRetrieved = $CachedProfile->DateRetrieved; return $CommunityProfile; } else { // ...if not, attempt to grab the profile's XML $CommunityProfile = simplexml_load_file('http://steamcommunity.com/profiles/' . $SteamID . '?xml=1', 'SimpleXMLElement', LIBXML_NOCDATA); // Were we able to successfully fetch the profile? if ($CommunityProfile && !isset($CommunityProfile->error)) { // ...if so, insert or update the profile XML into the cache table $this->SQL->Replace('SteamProfileCache', array('SteamID64' => $SteamID, 'ProfileXML' => $CommunityProfile->asXML(), 'DateRetrieved' => Gdn_Format::ToDateTime()), array('SteamID64' => $SteamID), TRUE); // Set the DateRetrieved record to now and go $CommunityProfile->DateRetrieved = Gdn_Format::ToDateTime(); return $CommunityProfile; } } } // If we hit this point, something bad has happened. return FALSE; }
public function Format($Html) { $Attributes = C('Garden.Html.BlockedAttributes', 'on*'); $Config = array('anti_link_spam' => array('`.`', ''), 'comment' => 1, 'cdata' => 3, 'css_expression' => 1, 'deny_attribute' => $Attributes, 'unique_ids' => 1, 'elements' => '*-applet-form-input-textarea-iframe-script-style-embed-object-select-option-button-fieldset-optgroup-legend', 'keep_bad' => 0, 'schemes' => 'classid:clsid; href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; style: nil; *:file, http, https', 'valid_xhtml' => 0, 'direct_list_nest' => 1, 'balance' => 1); // Turn embedded videos into simple links (legacy workaround) $Html = Gdn_Format::UnembedVideos($Html); // We check the flag within Gdn_Format to see // if htmLawed should place rel="nofollow" links // within output or not. // A plugin can set this flag (for example). // The default is to show rel="nofollow" on all links. if (Gdn_Format::$DisplayNoFollow) { // display rel="nofollow" on all links. $Config['anti_link_spam'] = array('`.`', ''); } else { // never display rel="nofollow" $Config['anti_link_spam'] = array('', ''); } if ($this->SafeStyles) { // Deny all class and style attributes. // A lot of damage can be done by hackers with these attributes. $Config['deny_attribute'] .= ',style'; // } else { // $Config['hook_tag'] = 'HTMLawedHookTag'; } // Block some IDs so you can't break Javascript $GLOBALS['hl_Ids'] = array('Bookmarks' => 1, 'CommentForm' => 1, 'Content' => 1, 'Definitions' => 1, 'DiscussionForm' => 1, 'Foot' => 1, 'Form_Comment' => 1, 'Form_User_Password' => 1, 'Form_User_SignIn' => 1, 'Head' => 1, 'HighlightColor' => 1, 'InformMessageStack' => 1, 'Menu' => 1, 'PagerMore' => 1, 'Panel' => 1, 'Status' => 1); $Spec = 'object=-classid-type, -codebase; embed=type(oneof=application/x-shockwave-flash); a=class(noneof=Hijack|Dismiss|MorePager/nomatch=%pop[in|up|down]|flyout|ajax%i)'; $Result = htmLawed($Html, $Config, $Spec); return $Result; }
public function DiscussionController_Render_Before(&$Sender) { $Sender->Head->AddTag('meta', array('content' => Gdn_Format::Text($Sender->Discussion->Name), 'property' => 'og:title')); $Sender->Head->AddTag('meta', array('content' => Gdn_Url::Request(true, true, true), 'property' => 'og:url')); $Sender->Head->AddTag('meta', array('content' => C('Garden.Title'), 'property' => 'og:site_name')); $Sender->Head->AddTag('meta', array('content' => 'article', 'property' => 'og:type')); $Sender->addJsFile('http://connect.facebook.net/en_US/all.js#xfbml=1'); }
/** * Filter provided HTML through htmlLawed and return the result. * * @param string $html String of HTML to filter. * @return string Returns the filtered HTML. */ public function format($html) { $attributes = c('Garden.Html.BlockedAttributes', 'on*'); $config = ['anti_link_spam' => ['`.`', ''], 'balance' => 1, 'cdata' => 3, 'comment' => 1, 'css_expression' => 1, 'deny_attribute' => $attributes, 'direct_list_nest' => 1, 'elements' => '*-applet-form-input-textarea-iframe-script-style-embed-object-select-option-button-fieldset-optgroup-legend', 'keep_bad' => 0, 'schemes' => 'classid:clsid; href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; style: nil; *:file, http, https', 'unique_ids' => 1, 'valid_xhtml' => 0]; // Turn embedded videos into simple links (legacy workaround) $html = Gdn_Format::unembedContent($html); // We check the flag within Gdn_Format to see // if htmLawed should place rel="nofollow" links // within output or not. // A plugin can set this flag (for example). // The default is to show rel="nofollow" on all links. if (Gdn_Format::$DisplayNoFollow) { // display rel="nofollow" on all links. $config['anti_link_spam'] = ['`.`', '']; } else { // never display rel="nofollow" $config['anti_link_spam'] = ['', '']; } // Deny all class and style attributes. // A lot of damage can be done by hackers with these attributes. $config['deny_attribute'] .= ',style,class'; // Block some IDs so you can't break Javascript $GLOBALS['hl_Ids'] = ['Bookmarks' => 1, 'CommentForm' => 1, 'Content' => 1, 'Definitions' => 1, 'DiscussionForm' => 1, 'Foot' => 1, 'Form_Comment' => 1, 'Form_User_Password' => 1, 'Form_User_SignIn' => 1, 'Head' => 1, 'HighlightColor' => 1, 'InformMessageStack' => 1, 'Menu' => 1, 'PagerMore' => 1, 'Panel' => 1, 'Status' => 1]; $spec = 'object=-classid-type, -codebase; embed=type(oneof=application/x-shockwave-flash); '; // Define elements allowed to have a `class`. $spec .= implode(',', $this->classedElements); // Whitelist classes we allow. $spec .= '=class(oneof=' . implode('|', $this->allowedClasses) . '); '; return Htmlawed::filter($html, $config, $spec); }
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] : []); }
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 }
public function Format($Html) { $Attributes = C('Garden.Html.BlockedAttributes', 'on*'); $Config = array('anti_link_spam' => array('`.`', ''), 'comment' => 1, 'cdata' => 3, 'css_expression' => 1, 'deny_attribute' => $Attributes, 'unique_ids' => 0, 'elements' => '*-applet-form-input-textarea-iframe-script-style-embed-object', 'keep_bad' => 0, 'schemes' => 'classid:clsid; href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; style: nil; *:file, http, https', 'valid_xhtml' => 0, 'direct_list_nest' => 1, 'balance' => 1); // Turn embedded videos into simple links (legacy workaround) $Html = Gdn_Format::UnembedContent($Html); // We check the flag within Gdn_Format to see // if htmLawed should place rel="nofollow" links // within output or not. // A plugin can set this flag (for example). // The default is to show rel="nofollow" on all links. if (Gdn_Format::$DisplayNoFollow) { // display rel="nofollow" on all links. $Config['anti_link_spam'] = array('`.`', ''); } else { // never display rel="nofollow" $Config['anti_link_spam'] = array('', ''); } if ($this->SafeStyles) { // Deny all class and style attributes. // A lot of damage can be done by hackers with these attributes. $Config['deny_attribute'] .= ',style'; // } else { // $Config['hook_tag'] = 'HTMLawedHookTag'; } $Spec = 'object=-classid-type, -codebase; embed=type(oneof=application/x-shockwave-flash)'; $Result = htmLawed($Html, $Config, $Spec); return $Result; }
/** * Checks to see if the user is spamming. Returns TRUE if the user is spamming. */ public function CheckForSpam($Type) { $Spam = FALSE; if (!in_array($Type, array('Comment', 'Discussion'))) { trigger_error(ErrorMessage(sprintf('Spam check type unknown: %s', $Type), 'VanillaModel', 'CheckForSpam'), E_USER_ERROR); } $Session = Gdn::Session(); $CountSpamCheck = $Session->GetAttribute('Count' . $Type . 'SpamCheck', 0); $DateSpamCheck = $Session->GetAttribute('Date' . $Type . 'SpamCheck', 0); $SecondsSinceSpamCheck = time() - Gdn_Format::ToTimestamp($DateSpamCheck); $SpamCount = Gdn::Config('Vanilla.' . $Type . '.SpamCount'); if (!is_numeric($SpamCount) || $SpamCount < 2) { $SpamCount = 2; } // 2 spam minimum $SpamTime = Gdn::Config('Vanilla.' . $Type . '.SpamTime'); if (!is_numeric($SpamTime) || $SpamTime < 0) { $SpamTime = 30; } // 30 second minimum spam span $SpamLock = Gdn::Config('Vanilla.' . $Type . '.SpamLock'); if (!is_numeric($SpamLock) || $SpamLock < 30) { $SpamLock = 30; } // 30 second minimum lockout // Definition: // Users cannot post more than $SpamCount comments within $SpamTime // seconds or their account will be locked for $SpamLock seconds. // Apply a spam lock if necessary $Attributes = array(); if ($SecondsSinceSpamCheck < $SpamLock && $CountSpamCheck >= $SpamCount && $DateSpamCheck !== FALSE) { // TODO: REMOVE DEBUGGING INFO AFTER THIS IS WORKING PROPERLY /* echo '<div>SecondsSinceSpamCheck: '.$SecondsSinceSpamCheck.'</div>'; echo '<div>SpamLock: '.$SpamLock.'</div>'; echo '<div>CountSpamCheck: '.$CountSpamCheck.'</div>'; echo '<div>SpamCount: '.$SpamCount.'</div>'; echo '<div>DateSpamCheck: '.$DateSpamCheck.'</div>'; echo '<div>SpamTime: '.$SpamTime.'</div>'; */ $Spam = TRUE; $this->Validation->AddValidationResult('Body', sprintf(T('You have posted %1$s times within %2$s seconds. A spam block is now in effect on your account. You must wait at least %3$s seconds before attempting to post again.'), $SpamCount, $SpamTime, $SpamLock)); // Update the 'waiting period' every time they try to post again $Attributes['Date' . $Type . 'SpamCheck'] = Gdn_Format::ToDateTime(); } else { if ($SecondsSinceSpamCheck > $SpamTime) { $Attributes['Count' . $Type . 'SpamCheck'] = 1; $Attributes['Date' . $Type . 'SpamCheck'] = Gdn_Format::ToDateTime(); } else { $Attributes['Count' . $Type . 'SpamCheck'] = $CountSpamCheck + 1; } } // Update the user profile after every comment $UserModel = Gdn::UserModel(); $UserModel->SaveAttribute($Session->UserID, $Attributes); return $Spam; }
public function Format($String) { try { $Result = parse_bbc($String); } catch (Exception $Ex) { $Result = '<!-- Error: ' . htmlspecialchars($Ex->getMessage()) . '-->' . Gdn_Format::Display($String); } return $Result; }
/** * Create the target category that is needed for this plugin to work. */ public function structure() { $category = (array) CategoryModel::instance()->getByCode('welcome'); $cachedCategoryID = val('CategoryID', $category, false); if (!$cachedCategoryID) { $categoryModel = CategoryModel::instance(); $categoryModel->save(['ParentCategoryID' => -1, 'Depth' => 1, 'InsertUserID' => 1, 'UpdateUserID' => 1, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime(), 'Name' => 'Welcome', 'UrlCode' => 'welcome', 'Description' => 'Introduce yourself to the community!', 'PermissionCategoryID' => -1]); } }
protected function _checkName($n) { $Result = parent::_checkName($n); $Extension = pathinfo($Result, 4); $Name = pathinfo($Result, 8); $Result = Gdn_Format::Clean($Name) . '.' . Gdn_Format::Clean($Extension); $Result = trim($Result, '.'); return $Result; }
public function Structure() { // Get a user for operations. $UserID = Gdn::SQL()->GetWhere('User', array('Name' => 'Mollom', 'Admin' => 2))->Value('UserID'); if (!$UserID) { $UserID = Gdn::SQL()->Insert('User', array('Name' => 'Mollom', 'Password' => RandomString('20'), 'HashMethod' => 'Random', 'Email' => '*****@*****.**', 'DateInserted' => Gdn_Format::ToDateTime(), 'Admin' => '2')); } SaveToConfig('Plugins.Mollom.UserID', $UserID); }
public function Search($Search, $Offset = 0, $Limit = 20) { $BaseUrl = C('Plugins.Solr.SearchUrl', 'http://localhost:8983/solr/select/?'); if (!$BaseUrl) { throw new Gdn_UserException("The search url has not been configured."); } if (!$Search) { return array(); } // Escepe the search. $Search = preg_replace('`([][+&|!(){}^"~*?:\\\\-])`', "\\\\\$1", $Search); // Add the category watch. $Categories = CategoryModel::CategoryWatch(); if ($Categories === FALSE) { return array(); } elseif ($Categories !== TRUE) { $Search = 'CategoryID:(' . implode(' ', $Categories) . ') AND ' . $Search; } // Build the search url. $BaseUrl .= strpos($BaseUrl, '?') === FALSE ? '?' : '&'; $Query = array('q' => $Search, 'start' => $Offset, 'rows' => $Limit); $Url = $BaseUrl . http_build_query($Query); // Grab the data. $Curl = curl_init($Url); curl_setopt($Curl, CURLOPT_RETURNTRANSFER, 1); $CurlResult = curl_exec($Curl); curl_close($Curl); // Parse the result into the form that the search controller expects. $Xml = new SimpleXMLElement($CurlResult); $Result = array(); if (!isset($Xml->result)) { return array(); } foreach ($Xml->result->children() as $Doc) { $Row = array(); foreach ($Doc->children() as $Field) { $Name = (string) $Field['name']; $Row[$Name] = (string) $Field; } // Add the url. switch ($Row['DocType']) { case 'Discussion': $Row['Url'] = '/discussion/' . $Row['PrimaryID'] . '/' . Gdn_Format::Url($Row['Title']); break; case 'Comment': $Row['Url'] = "/discussion/comment/{$Row['PrimaryID']}/#Comment_{$Row['PrimaryID']}"; break; } // Fix the time. $Row['DateInserted'] = strtotime($Row['DateInserted']); $Result[] = $Row; } // Join the users into the result. Gdn_DataSet::Join($Result, array('table' => 'User', 'parent' => 'UserID', 'prefix' => '', 'Name', 'Photo')); return $Result; }
/** * Add prefix to the passed controller's discussion names when they are re: an addon. * * Ex: [AddonName] Discussion original name * * @param array $Discussion */ public function addonDiscussionPrefix($Discussion) { $Addon = val('Addon', $Discussion); if ($Addon) { $Slug = AddonModel::slug($Addon, false); $Url = "/addon/{$Slug}"; $AddonName = val('Name', $Addon); echo ' ' . wrap(anchor(Gdn_Format::html($AddonName), $Url), 'span', array('class' => 'Tag Tag-Addon')) . ' '; } }
public function renderOrigin($Sender) { $Discussion = $Sender->EventArguments['Discussion']; if ($Discussion !== NULL && $Discussion->LastCommentID != '') { $Creator = UserBuilder($Discussion, 'First'); $CreationDate = $Discussion->DateInserted; echo ' <span class="MItem LastCommentBy">' . sprintf(T('Started by %1$s'), UserAnchor($Creator)) . '</span>'; echo ' <span class="MItem LastCommentDate">' . Gdn_Format::Date($CreationDate, 'html') . '</span>'; } }
public function MarkRead($CategoryID, $TKey) { if (Gdn::Session()->ValidateTransientKey($TKey)) { $this->CategoryModel->SaveUserTree($CategoryID, array('DateMarkedRead' => Gdn_Format::ToDateTime())); } if ($this->DeliveryType() == DELIVERY_TYPE_ALL) { Redirect('/categories'); } $this->Render(); }
/** * Render the given view. * * @param string $Path The path to the view's file. * @param Controller $Controller The controller that is rendering the view. */ public function Render($Path, $Controller) { $Smarty = $this->Smarty(); // Get a friendly name for the controller. $ControllerName = get_class($Controller); if (StringEndsWith($ControllerName, 'Controller', TRUE)) { $ControllerName = substr($ControllerName, 0, -10); } // Get an ID for the body. $BodyIdentifier = strtolower($Controller->ApplicationFolder.'_'.$ControllerName.'_'.Gdn_Format::AlphaNumeric(strtolower($Controller->RequestMethod))); $Smarty->assign('BodyID', $BodyIdentifier); //$Smarty->assign('Config', Gdn::Config()); // Assign some information about the user. $Session = Gdn::Session(); if($Session->IsValid()) { $User = array( 'Name' => $Session->User->Name, 'CountNotifications' => (int)GetValue('CountNotifications', $Session->User->CountNotifications, 0), 'CountUnreadConversations' => (int)GetValue('CountUnreadConversations', $Session->User, 0), 'SignedIn' => TRUE); } else { $User = FALSE; /*array( 'Name' => '', 'CountNotifications' => 0, 'SignedIn' => FALSE);*/ } $Smarty->assign('User', $User); // Make sure that any datasets use arrays instead of objects. foreach($Controller->Data as $Key => $Value) { if($Value instanceof Gdn_DataSet) { $Controller->Data[$Key] = $Value->ResultArray(); } elseif($Value instanceof stdClass) { $Controller->Data[$Key] = (array)$Value; } } $Controller->Data['BodyClass'] = GetValue('CssClass', $Controller->Data, '', TRUE); $Smarty->assign('Assets', (array)$Controller->Assets); $Smarty->assign('Path', Gdn::Request()->Path()); // Assigign the controller data last so the controllers override any default data. $Smarty->assign($Controller->Data); $Smarty->Controller = $Controller; // for smarty plugins $Smarty->security = TRUE; $Smarty->security_settings['IF_FUNCS'] = array_merge($Smarty->security_settings['IF_FUNCS'], array('CheckPermission', 'GetValue', 'SetValue', 'Url')); $Smarty->secure_dir = array($Path); $Smarty->display($Path); }
function DoVideo($bbcode, $action, $name, $default, $params, $content) { list($Width, $Height) = Gdn_Format::GetEmbedSize(); list($Type, $Code) = explode(';', $default); switch ($Type) { case 'youtube': return '<div class="Video P"><iframe width="' . $Width . '" height="' . $Height . '" src="http://www.youtube.com/embed/' . $Code . '" frameborder="0" allowfullscreen></iframe></div>'; default: return $content; } }