/** * Build HTML. * * @return string HTML. */ 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(val('Name', $User), 'span', array('class' => 'Username')), 'span'), userUrl($User)); ?> </li> <?php } ?> </ul> </div> <?php $String = ob_get_contents(); @ob_end_clean(); return $String; }
/** * Output 'edited' notice. * * @param $Sender */ protected function drawEdited($Sender) { $Record = $Sender->data('Discussion'); if (!$Record) { $Record = $Sender->data('Record'); } if (!$Record) { return; } $PermissionCategoryID = val('PermissionCategoryID', $Record); $Data = $Record; $RecordType = 'discussion'; $RecordID = val('DiscussionID', $Data); // But override if comment if (isset($Sender->EventArguments['Comment']) || val('RecordType', $Record) == 'comment') { $Data = $Sender->EventArguments['Comment']; $RecordType = 'comment'; $RecordID = val('CommentID', $Data); } $UserCanEdit = Gdn::session()->checkPermission('Vanilla.' . ucfirst($RecordType) . 's.Edit', true, 'Category', $PermissionCategoryID); if (is_null($Data->DateUpdated)) { return; } // Do not show log link if no log would have been generated. $elapsed = Gdn_Format::toTimestamp(val('DateUpdated', $Data)) - Gdn_Format::toTimestamp(val('DateInserted', $Data)); $grace = c('Garden.Log.FloodControl', 20) * 60; if ($elapsed < $grace) { return; } $UpdatedUserID = $Data->UpdateUserID; $UserData = Gdn::userModel()->getID($UpdatedUserID); $Edited = array('EditUser' => val('Name', $UserData, t('Unknown User')), 'EditDate' => Gdn_Format::date($Data->DateUpdated, 'html'), 'EditLogUrl' => url("/log/record/{$RecordType}/{$RecordID}"), 'EditWord' => 'at'); $DateUpdateTime = Gdn_Format::toTimestamp($Data->DateUpdated); if (date('ymd', $DateUpdateTime) != date('ymd')) { $Edited['EditWord'] = 'on'; } $Format = t('PostEdited.Plain', 'Post edited by {EditUser} {EditWord} {EditDate}'); if ($UserCanEdit) { $Format = t('PostEdited.Log', 'Post edited by {EditUser} {EditWord} {EditDate} (<a href="{EditLogUrl}">log</a>)'); } echo '<div class="PostEdited">' . formatString($Format, $Edited) . '</div>'; }
/** * Writes a discussion in table row format. */ function writeDiscussionRow($Discussion, $Sender, $Session) { if (!property_exists($Sender, 'CanEditDiscussions')) { $Sender->CanEditDiscussions = val('PermsDiscussionsEdit', CategoryModel::categories($Discussion->CategoryID)) && c('Vanilla.AdminCheckboxes.Use'); } $CssClass = CssClass($Discussion); $DiscussionUrl = $Discussion->Url; if ($Session->UserID) { $DiscussionUrl .= '#latest'; } $Sender->EventArguments['DiscussionUrl'] =& $DiscussionUrl; $Sender->EventArguments['Discussion'] =& $Discussion; $Sender->EventArguments['CssClass'] =& $CssClass; $First = UserBuilder($Discussion, 'First'); if ($Discussion->LastUserID) { $Last = UserBuilder($Discussion, 'Last'); } else { $Last = $First; } $Sender->EventArguments['FirstUser'] =& $First; $Sender->EventArguments['LastUser'] =& $Last; $Sender->fireEvent('BeforeDiscussionName'); $DiscussionName = $Discussion->Name; // If there are no word character detected in the title treat it as if it is blank. if (!preg_match('/\\w/u', $DiscussionName)) { $DiscussionName = t('Blank Discussion Topic'); } $Sender->EventArguments['DiscussionName'] =& $DiscussionName; static $FirstDiscussion = true; if (!$FirstDiscussion) { $Sender->fireEvent('BetweenDiscussion'); } else { $FirstDiscussion = false; } $Discussion->CountPages = ceil($Discussion->CountComments / $Sender->CountCommentsPerPage); $FirstPageUrl = DiscussionUrl($Discussion, 1); $LastPageUrl = DiscussionUrl($Discussion, val('CountPages', $Discussion)) . '#latest'; ?> <tr id="Discussion_<?php echo $Discussion->DiscussionID; ?> " class="<?php echo $CssClass; ?> "> <?php $Sender->fireEvent('BeforeDiscussionContent'); ?> <?php echo AdminCheck($Discussion, array('<td class="CheckBoxColumn"><div class="Wrap">', '</div></td>')); ?> <td class="DiscussionName"> <div class="Wrap"> <span class="Options"> <?php echo OptionsList($Discussion); echo BookmarkButton($Discussion); ?> </span> <?php $Sender->fireEvent('BeforeDiscussionTitle'); echo anchor($DiscussionName, $DiscussionUrl, 'Title') . ' '; $Sender->fireEvent('AfterDiscussionTitle'); WriteMiniPager($Discussion); echo NewComments($Discussion); if ($Sender->data('_ShowCategoryLink', true)) { echo CategoryLink($Discussion, ' ' . t('in') . ' '); } // Other stuff that was in the standard view that you may want to display: echo '<div class="Meta Meta-Discussion">'; WriteTags($Discussion); echo '</div>'; // if ($Source = val('Source', $Discussion)) // echo ' '.sprintf(t('via %s'), t($Source.' Source', $Source)); // ?> </div> </td> <td class="BlockColumn BlockColumn-User FirstUser"> <div class="Block Wrap"> <?php echo userPhoto($First, array('Size' => 'Small')); echo userAnchor($First, 'UserLink BlockTitle'); echo '<div class="Meta">'; echo anchor(Gdn_Format::date($Discussion->FirstDate, 'html'), $FirstPageUrl, 'CommentDate MItem'); echo '</div>'; ?> </div> </td> <td class="BigCount CountComments"> <div class="Wrap"> <?php // Exact Number // echo number_format($Discussion->CountComments); // Round Number echo BigPlural($Discussion->CountComments, '%s comment'); ?> </div> </td> <td class="BigCount CountViews"> <div class="Wrap"> <?php // Exact Number // echo number_format($Discussion->CountViews); // Round Number echo BigPlural($Discussion->CountViews, '%s view'); ?> </div> </td> <td class="BlockColumn BlockColumn-User LastUser"> <div class="Block Wrap"> <?php if ($Last) { echo userPhoto($Last, array('Size' => 'Small')); echo userAnchor($Last, 'UserLink BlockTitle'); echo '<div class="Meta">'; echo anchor(Gdn_Format::date($Discussion->LastDate, 'html'), $LastPageUrl, 'CommentDate MItem'); echo '</div>'; } else { echo ' '; } ?> </div> </td> </tr> <?php }
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); } } }
?> </td> <td class="Alt"><?php if ($Invitation->AcceptedName == '') { echo t('Pending'); } else { echo t('Accepted'); } ?> </td> <td> <?php if (!$Invitation->DateExpires) { echo t('Never expires', 'Never'); } else { echo Gdn_Format::date($Invitation->DateExpires, 'html'); } ?> </td> <?php // <td><?php echo $Invitation->Code; <!--</td>--> ?> </tr> <?php } ?> </tbody> </table> <?php } echo $this->Form->close();
/** * Get number of available invites a user has. * * @param int $UserID * @return int */ public function getInvitationCount($UserID) { // If this user is master admin, they should have unlimited invites. if ($this->SQL->select('UserID')->from('User')->where('UserID', $UserID)->where('Admin', '1')->get()->numRows() > 0) { return -1; } // Get the Registration.InviteRoles settings: $InviteRoles = Gdn::config('Garden.Registration.InviteRoles', []); if (!is_array($InviteRoles) || count($InviteRoles) == 0) { return 0; } // Build an array of roles that can send invitations $CanInviteRoles = []; foreach ($InviteRoles as $RoleID => $Invites) { if ($Invites > 0 || $Invites == -1) { $CanInviteRoles[] = $RoleID; } } if (count($CanInviteRoles) == 0) { return 0; } // See which matching roles the user has $UserRoleData = $this->SQL->select('RoleID')->from('UserRole')->where('UserID', $UserID)->whereIn('RoleID', $CanInviteRoles)->get(); if ($UserRoleData->numRows() == 0) { return 0; } // Define the maximum number of invites the user is allowed to send $InviteCount = 0; foreach ($UserRoleData->result() as $UserRole) { $Count = $InviteRoles[$UserRole->RoleID]; if ($Count == -1) { $InviteCount = -1; } elseif ($InviteCount != -1 && $Count > $InviteCount) { $InviteCount = $Count; } } // If the user has unlimited invitations, return that value if ($InviteCount == -1) { return -1; } // Get the user's current invitation settings from their profile $User = $this->SQL->select('CountInvitations, DateSetInvitations')->from('User')->where('UserID', $UserID)->get()->firstRow(); // If CountInvitations is null (ie. never been set before) or it is a new month since the DateSetInvitations if ($User->CountInvitations == '' || is_null($User->DateSetInvitations) || Gdn_Format::date($User->DateSetInvitations, '%m %Y') != Gdn_Format::date('', '%m %Y')) { // Reset CountInvitations and DateSetInvitations $this->SQL->put($this->Name, ['CountInvitations' => $InviteCount, 'DateSetInvitations' => Gdn_Format::date('', '%Y-%m-01')], ['UserID' => $UserID]); return $InviteCount; } else { // Otherwise return CountInvitations return $User->CountInvitations; } }
/** * The callback helper for {@link formatString()}. * * @param array $Match Either the array of arguments or the regular expression match. * @param bool $SetArgs Whether this is a call to initialize the arguments or a matching callback. * @return mixed Returns the matching string or nothing when setting the arguments. * @access private */ function _formatStringCallback($Match, $SetArgs = false) { static $Args = array(), $ContextUserID = null; if ($SetArgs) { $Args = $Match; if (isset($Args['_ContextUserID'])) { $ContextUserID = $Args['_ContextUserID']; } else { $ContextUserID = Gdn::session() && Gdn::session()->isValid() ? Gdn::session()->UserID : null; } return ''; } $Match = $Match[1]; if ($Match == '{') { return $Match; } // Parse out the field and format. $Parts = explode(',', $Match); $Field = trim($Parts[0]); $Format = trim(val(1, $Parts, '')); $SubFormat = strtolower(trim(val(2, $Parts, ''))); $FormatArgs = val(3, $Parts, ''); if (in_array($Format, array('currency', 'integer', 'percent'))) { $FormatArgs = $SubFormat; $SubFormat = $Format; $Format = 'number'; } elseif (is_numeric($SubFormat)) { $FormatArgs = $SubFormat; $SubFormat = ''; } $Value = valr($Field, $Args, null); if ($Value === null && !in_array($Format, array('url', 'exurl', 'number', 'plural'))) { $Result = ''; } else { switch (strtolower($Format)) { case 'date': switch ($SubFormat) { case 'short': $Result = Gdn_Format::date($Value, '%d/%m/%Y'); break; case 'medium': $Result = Gdn_Format::date($Value, '%e %b %Y'); break; case 'long': $Result = Gdn_Format::date($Value, '%e %B %Y'); break; default: $Result = Gdn_Format::date($Value); break; } break; case 'html': case 'htmlspecialchars': $Result = htmlspecialchars($Value); break; case 'number': if (!is_numeric($Value)) { $Result = $Value; } else { switch ($SubFormat) { case 'currency': $Result = '$' . number_format($Value, is_numeric($FormatArgs) ? $FormatArgs : 2); break; case 'integer': $Result = (string) round($Value); if (is_numeric($FormatArgs) && strlen($Result) < $FormatArgs) { $Result = str_repeat('0', $FormatArgs - strlen($Result)) . $Result; } break; case 'percent': $Result = round($Value * 100, is_numeric($FormatArgs) ? $FormatArgs : 0); break; default: $Result = number_format($Value, is_numeric($FormatArgs) ? $FormatArgs : 0); break; } } break; case 'plural': if (is_array($Value)) { $Value = count($Value); } elseif (StringEndsWith($Field, 'UserID', true)) { $Value = 1; } if (!is_numeric($Value)) { $Result = $Value; } else { if (!$SubFormat) { $SubFormat = rtrim("%s {$Field}", 's'); } if (!$FormatArgs) { $FormatArgs = $SubFormat . 's'; } $Result = Plural($Value, $SubFormat, $FormatArgs); } break; case 'rawurlencode': $Result = rawurlencode($Value); break; case 'text': $Result = Gdn_Format::text($Value, false); break; case 'time': $Result = Gdn_Format::date($Value, '%l:%M%p'); break; case 'url': if (strpos($Field, '/') !== false) { $Value = $Field; } $Result = Url($Value, $SubFormat == 'domain'); break; case 'exurl': if (strpos($Field, '/') !== false) { $Value = $Field; } $Result = externalUrl($Value); break; case 'urlencode': $Result = urlencode($Value); break; case 'gender': // Format in the form of FieldName,gender,male,female,unknown[,plural] if (is_array($Value) && count($Value) == 1) { $Value = array_shift($Value); } $Gender = 'u'; if (!is_array($Value)) { $User = Gdn::userModel()->getID($Value); if ($User) { $Gender = $User->Gender; } } else { $Gender = 'p'; } switch ($Gender) { case 'm': $Result = $SubFormat; break; case 'f': $Result = $FormatArgs; break; case 'p': $Result = val(5, $Parts, val(4, $Parts)); break; case 'u': default: $Result = val(4, $Parts); } break; case 'user': case 'you': case 'his': case 'her': case 'your': // $Result = print_r($Value, true); $ArgsBak = $Args; if (is_array($Value) && count($Value) == 1) { $Value = array_shift($Value); } if (is_array($Value)) { if (isset($Value['UserID'])) { $User = $Value; $User['Name'] = formatUsername($User, $Format, $ContextUserID); $Result = userAnchor($User); } else { $Max = c('Garden.FormatUsername.Max', 5); // See if there is another count. $ExtraCount = valr($Field . '_Count', $Args, 0); $Count = count($Value); $Result = ''; for ($i = 0; $i < $Count; $i++) { if ($i >= $Max && $Count > $Max + 1) { $Others = $Count - $i + $ExtraCount; $Result .= ' ' . t('sep and', 'and') . ' ' . plural($Others, '%s other', '%s others'); break; } $ID = $Value[$i]; if (is_array($ID)) { continue; } if ($i == $Count - 1) { $Result .= ' ' . T('sep and', 'and') . ' '; } elseif ($i > 0) { $Result .= ', '; } $Special = array(-1 => T('everyone'), -2 => T('moderators'), -3 => T('administrators')); if (isset($Special[$ID])) { $Result .= $Special[$ID]; } else { $User = Gdn::userModel()->getID($ID); if ($User) { $User->Name = formatUsername($User, $Format, $ContextUserID); $Result .= userAnchor($User); } } } } } else { $User = Gdn::userModel()->getID($Value); if ($User) { // Store this name separately because of special 'You' case. $Name = formatUsername($User, $Format, $ContextUserID); // Manually build instead of using userAnchor() because of special 'You' case. $Result = anchor(htmlspecialchars($Name), userUrl($User)); } else { $Result = ''; } } $Args = $ArgsBak; break; default: $Result = $Value; break; } } return $Result; }
/** * Create or update a comment. * * @since 2.0.0 * @access public * * @param int $DiscussionID Unique ID to add the comment to. If blank, this method will throw an error. */ public function comment($DiscussionID = '') { // Get $DiscussionID from RequestArgs if valid if ($DiscussionID == '' && count($this->RequestArgs)) { if (is_numeric($this->RequestArgs[0])) { $DiscussionID = $this->RequestArgs[0]; } } // If invalid $DiscussionID, get from form. $this->Form->setModel($this->CommentModel); $DiscussionID = is_numeric($DiscussionID) ? $DiscussionID : $this->Form->getFormValue('DiscussionID', 0); // Set discussion data $this->DiscussionID = $DiscussionID; $this->Discussion = $Discussion = $this->DiscussionModel->getID($DiscussionID); // Is this an embedded comment being posted to a discussion that doesn't exist yet? $vanilla_type = $this->Form->getFormValue('vanilla_type', ''); $vanilla_url = $this->Form->getFormValue('vanilla_url', ''); $vanilla_category_id = $this->Form->getFormValue('vanilla_category_id', ''); $Attributes = array('ForeignUrl' => $vanilla_url); $vanilla_identifier = $this->Form->getFormValue('vanilla_identifier', ''); $isEmbeddedComments = $vanilla_url != '' && $vanilla_identifier != ''; // Only allow vanilla identifiers of 32 chars or less - md5 if larger if (strlen($vanilla_identifier) > 32) { $Attributes['vanilla_identifier'] = $vanilla_identifier; $vanilla_identifier = md5($vanilla_identifier); } if (!$Discussion && $isEmbeddedComments) { $Discussion = $Discussion = $this->DiscussionModel->getForeignID($vanilla_identifier, $vanilla_type); if ($Discussion) { $this->DiscussionID = $DiscussionID = $Discussion->DiscussionID; $this->Form->setValue('DiscussionID', $DiscussionID); } } // If so, create it! if (!$Discussion && $isEmbeddedComments) { // Add these values back to the form if they exist! $this->Form->addHidden('vanilla_identifier', $vanilla_identifier); $this->Form->addHidden('vanilla_type', $vanilla_type); $this->Form->addHidden('vanilla_url', $vanilla_url); $this->Form->addHidden('vanilla_category_id', $vanilla_category_id); $PageInfo = fetchPageInfo($vanilla_url); if (!($Title = $this->Form->getFormValue('Name'))) { $Title = val('Title', $PageInfo, ''); if ($Title == '') { $Title = t('Undefined discussion subject.'); if (!empty($PageInfo['Exception']) && $PageInfo['Exception'] === "Couldn't connect to host.") { $Title .= ' ' . t('Page timed out.'); } } } $Description = val('Description', $PageInfo, ''); $Images = val('Images', $PageInfo, array()); $LinkText = t('EmbededDiscussionLinkText', 'Read the full story here'); if (!$Description && count($Images) == 0) { $Body = formatString('<p><a href="{Url}">{LinkText}</a></p>', array('Url' => $vanilla_url, 'LinkText' => $LinkText)); } else { $Body = formatString(' <div class="EmbeddedContent">{Image}<strong>{Title}</strong> <p>{Excerpt}</p> <p><a href="{Url}">{LinkText}</a></p> <div class="ClearFix"></div> </div>', array('Title' => $Title, 'Excerpt' => $Description, 'Image' => count($Images) > 0 ? img(val(0, $Images), array('class' => 'LeftAlign')) : '', 'Url' => $vanilla_url, 'LinkText' => $LinkText)); } if ($Body == '') { $Body = $vanilla_url; } if ($Body == '') { $Body = t('Undefined discussion body.'); } // Validate the CategoryID for inserting. $Category = CategoryModel::categories($vanilla_category_id); if (!$Category) { $vanilla_category_id = c('Vanilla.Embed.DefaultCategoryID', 0); if ($vanilla_category_id <= 0) { // No default category defined, so grab the first non-root category and use that. $vanilla_category_id = $this->DiscussionModel->SQL->select('CategoryID')->from('Category')->where('CategoryID >', 0)->get()->firstRow()->CategoryID; // No categories in the db? default to 0 if (!$vanilla_category_id) { $vanilla_category_id = 0; } } } else { $vanilla_category_id = $Category['CategoryID']; } $EmbedUserID = c('Garden.Embed.UserID'); if ($EmbedUserID) { $EmbedUser = Gdn::userModel()->getID($EmbedUserID); } if (!$EmbedUserID || !$EmbedUser) { $EmbedUserID = Gdn::userModel()->getSystemUserID(); } $EmbeddedDiscussionData = array('InsertUserID' => $EmbedUserID, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime(), 'CategoryID' => $vanilla_category_id, 'ForeignID' => $vanilla_identifier, 'Type' => $vanilla_type, 'Name' => $Title, 'Body' => $Body, 'Format' => 'Html', 'Attributes' => dbencode($Attributes)); $this->EventArguments['Discussion'] =& $EmbeddedDiscussionData; $this->fireEvent('BeforeEmbedDiscussion'); $DiscussionID = $this->DiscussionModel->SQL->insert('Discussion', $EmbeddedDiscussionData); $ValidationResults = $this->DiscussionModel->validationResults(); if (count($ValidationResults) == 0 && $DiscussionID > 0) { $this->Form->addHidden('DiscussionID', $DiscussionID); // Put this in the form so reposts won't cause new discussions. $this->Form->setFormValue('DiscussionID', $DiscussionID); // Put this in the form values so it is used when saving comments. $this->setJson('DiscussionID', $DiscussionID); $this->Discussion = $Discussion = $this->DiscussionModel->getID($DiscussionID, DATASET_TYPE_OBJECT, array('Slave' => false)); // Update the category discussion count if ($vanilla_category_id > 0) { $this->DiscussionModel->updateDiscussionCount($vanilla_category_id, $DiscussionID); } } } // If no discussion was found, error out if (!$Discussion) { $this->Form->addError(t('Failed to find discussion for commenting.')); } /** * Special care is taken for embedded comments. Since we don't currently use an advanced editor for these * comments, we may need to apply certain filters and fixes to the data to maintain its intended display * with the input format (e.g. maintaining newlines). */ if ($isEmbeddedComments) { $inputFormatter = $this->Form->getFormValue('Format', c('Garden.InputFormatter')); switch ($inputFormatter) { case 'Wysiwyg': $this->Form->setFormValue('Body', nl2br($this->Form->getFormValue('Body'))); break; } } $PermissionCategoryID = val('PermissionCategoryID', $Discussion); // Setup head $this->addJsFile('jquery.autosize.min.js'); $this->addJsFile('autosave.js'); $this->addJsFile('post.js'); // Setup comment model, $CommentID, $DraftID $Session = Gdn::session(); $CommentID = isset($this->Comment) && property_exists($this->Comment, 'CommentID') ? $this->Comment->CommentID : ''; $DraftID = isset($this->Comment) && property_exists($this->Comment, 'DraftID') ? $this->Comment->DraftID : ''; $this->EventArguments['CommentID'] = $CommentID; $this->EventArguments['DraftID'] = $DraftID; // Determine whether we are editing $Editing = $CommentID > 0 || $DraftID > 0; $this->EventArguments['Editing'] = $Editing; // If closed, cancel & go to discussion if ($Discussion && $Discussion->Closed == 1 && !$Editing && !$Session->checkPermission('Vanilla.Discussions.Close', true, 'Category', $PermissionCategoryID)) { redirect(DiscussionUrl($Discussion)); } // Add hidden IDs to form $this->Form->addHidden('DiscussionID', $DiscussionID); $this->Form->addHidden('CommentID', $CommentID); $this->Form->addHidden('DraftID', $DraftID, true); // Check permissions if ($Discussion && $Editing) { // Permission to edit if ($this->Comment->InsertUserID != $Session->UserID) { $this->permission('Vanilla.Comments.Edit', true, 'Category', $Discussion->PermissionCategoryID); } // Make sure that content can (still) be edited. $EditContentTimeout = c('Garden.EditContentTimeout', -1); $CanEdit = $EditContentTimeout == -1 || strtotime($this->Comment->DateInserted) + $EditContentTimeout > time(); if (!$CanEdit) { $this->permission('Vanilla.Comments.Edit', true, 'Category', $Discussion->PermissionCategoryID); } // Make sure only moderators can edit closed things if ($Discussion->Closed) { $this->permission('Vanilla.Comments.Edit', true, 'Category', $Discussion->PermissionCategoryID); } $this->Form->setFormValue('CommentID', $CommentID); } elseif ($Discussion) { // Permission to add $this->permission('Vanilla.Comments.Add', true, 'Category', $Discussion->PermissionCategoryID); } if ($this->Form->authenticatedPostBack()) { // Save as a draft? $FormValues = $this->Form->formValues(); $FormValues = $this->CommentModel->filterForm($FormValues); if (!$Editing) { unset($FormValues['CommentID']); } if ($DraftID == 0) { $DraftID = $this->Form->getFormValue('DraftID', 0); } $Type = GetIncomingValue('Type'); $Draft = $Type == 'Draft'; $this->EventArguments['Draft'] = $Draft; $Preview = $Type == 'Preview'; if ($Draft) { $DraftID = $this->DraftModel->save($FormValues); $this->Form->addHidden('DraftID', $DraftID, true); $this->Form->setValidationResults($this->DraftModel->validationResults()); } elseif (!$Preview) { // Fix an undefined title if we can. if ($this->Form->getFormValue('Name') && val('Name', $Discussion) == t('Undefined discussion subject.')) { $Set = array('Name' => $this->Form->getFormValue('Name')); if (isset($vanilla_url) && $vanilla_url && strpos(val('Body', $Discussion), t('Undefined discussion subject.')) !== false) { $LinkText = t('EmbededDiscussionLinkText', 'Read the full story here'); $Set['Body'] = formatString('<p><a href="{Url}">{LinkText}</a></p>', array('Url' => $vanilla_url, 'LinkText' => $LinkText)); } $this->DiscussionModel->setField(val('DiscussionID', $Discussion), $Set); } $Inserted = !$CommentID; $CommentID = $this->CommentModel->save($FormValues); // The comment is now half-saved. if (is_numeric($CommentID) && $CommentID > 0) { if (in_array($this->deliveryType(), array(DELIVERY_TYPE_ALL, DELIVERY_TYPE_DATA))) { $this->CommentModel->save2($CommentID, $Inserted, true, true); } else { $this->jsonTarget('', url("/post/comment2.json?commentid={$CommentID}&inserted={$Inserted}"), 'Ajax'); } // $Discussion = $this->DiscussionModel->getID($DiscussionID); $Comment = $this->CommentModel->getID($CommentID, DATASET_TYPE_OBJECT, array('Slave' => false)); $this->EventArguments['Discussion'] = $Discussion; $this->EventArguments['Comment'] = $Comment; $this->fireEvent('AfterCommentSave'); } elseif ($CommentID === SPAM || $CommentID === UNAPPROVED) { $this->StatusMessage = t('CommentRequiresApprovalStatus', 'Your comment will appear after it is approved.'); } $this->Form->setValidationResults($this->CommentModel->validationResults()); if ($CommentID > 0 && $DraftID > 0) { $this->DraftModel->delete($DraftID); } } // Handle non-ajax requests first: if ($this->_DeliveryType == DELIVERY_TYPE_ALL) { if ($this->Form->errorCount() == 0) { // Make sure that this form knows what comment we are editing. if ($CommentID > 0) { $this->Form->addHidden('CommentID', $CommentID); } // If the comment was not a draft if (!$Draft) { // Redirect to the new comment. if ($CommentID > 0) { redirect("discussion/comment/{$CommentID}/#Comment_{$CommentID}"); } elseif ($CommentID == SPAM) { $this->setData('DiscussionUrl', DiscussionUrl($Discussion)); $this->View = 'Spam'; } } elseif ($Preview) { // If this was a preview click, create a comment shell with the values for this comment $this->Comment = new stdClass(); $this->Comment->InsertUserID = $Session->User->UserID; $this->Comment->InsertName = $Session->User->Name; $this->Comment->InsertPhoto = $Session->User->Photo; $this->Comment->DateInserted = Gdn_Format::date(); $this->Comment->Body = val('Body', $FormValues, ''); $this->Comment->Format = val('Format', $FormValues, c('Garden.InputFormatter')); $this->addAsset('Content', $this->fetchView('preview')); } else { // If this was a draft save, notify the user about the save $this->informMessage(sprintf(t('Draft saved at %s'), Gdn_Format::date())); } } } else { // Handle ajax-based requests if ($this->Form->errorCount() > 0) { // Return the form errors $this->errorMessage($this->Form->errors()); } else { // Make sure that the ajax request form knows about the newly created comment or draft id $this->setJson('CommentID', $CommentID); $this->setJson('DraftID', $DraftID); if ($Preview) { // If this was a preview click, create a comment shell with the values for this comment $this->Comment = new stdClass(); $this->Comment->InsertUserID = $Session->User->UserID; $this->Comment->InsertName = $Session->User->Name; $this->Comment->InsertPhoto = $Session->User->Photo; $this->Comment->DateInserted = Gdn_Format::date(); $this->Comment->Body = val('Body', $FormValues, ''); $this->Comment->Format = val('Format', $FormValues, c('Garden.InputFormatter')); $this->View = 'preview'; } elseif (!$Draft) { // If the comment was not a draft // If Editing a comment if ($Editing) { // Just reload the comment in question $this->Offset = 1; $Comments = $this->CommentModel->getIDData($CommentID, array('Slave' => false)); $this->setData('Comments', $Comments); $this->setData('Discussion', $Discussion); // Load the discussion $this->ControllerName = 'discussion'; $this->View = 'comments'; // Also define the discussion url in case this request came from the post screen and needs to be redirected to the discussion $this->setJson('DiscussionUrl', DiscussionUrl($this->Discussion) . '#Comment_' . $CommentID); } else { // If the comment model isn't sorted by DateInserted or CommentID then we can't do any fancy loading of comments. $OrderBy = valr('0.0', $this->CommentModel->orderBy()); // $Redirect = !in_array($OrderBy, array('c.DateInserted', 'c.CommentID')); // $DisplayNewCommentOnly = $this->Form->getFormValue('DisplayNewCommentOnly'); // if (!$Redirect) { // // Otherwise load all new comments that the user hasn't seen yet // $LastCommentID = $this->Form->getFormValue('LastCommentID'); // if (!is_numeric($LastCommentID)) // $LastCommentID = $CommentID - 1; // Failsafe back to this new comment if the lastcommentid was not defined properly // // // Don't reload the first comment if this new comment is the first one. // $this->Offset = $LastCommentID == 0 ? 1 : $this->CommentModel->GetOffset($LastCommentID); // // Do not load more than a single page of data... // $Limit = c('Vanilla.Comments.PerPage', 30); // // // Redirect if the new new comment isn't on the same page. // $Redirect |= !$DisplayNewCommentOnly && PageNumber($this->Offset, $Limit) != PageNumber($Discussion->CountComments - 1, $Limit); // } // if ($Redirect) { // // The user posted a comment on a page other than the last one, so just redirect to the last page. // $this->RedirectUrl = Gdn::request()->Url("discussion/comment/$CommentID/#Comment_$CommentID", true); // } else { // // Make sure to load all new comments since the page was last loaded by this user // if ($DisplayNewCommentOnly) $this->Offset = $this->CommentModel->GetOffset($CommentID); $Comments = $this->CommentModel->GetIDData($CommentID, array('Slave' => false)); $this->setData('Comments', $Comments); $this->setData('NewComments', true); $this->ClassName = 'DiscussionController'; $this->ControllerName = 'discussion'; $this->View = 'comments'; // } // Make sure to set the user's discussion watch records $CountComments = $this->CommentModel->getCount($DiscussionID); $Limit = is_object($this->data('Comments')) ? $this->data('Comments')->numRows() : $Discussion->CountComments; $Offset = $CountComments - $Limit; $this->CommentModel->SetWatch($this->Discussion, $Limit, $Offset, $CountComments); } } else { // If this was a draft save, notify the user about the save $this->informMessage(sprintf(t('Draft saved at %s'), Gdn_Format::date())); } // And update the draft count $UserModel = Gdn::userModel(); $CountDrafts = $UserModel->getAttribute($Session->UserID, 'CountDrafts', 0); $this->setJson('MyDrafts', t('My Drafts')); $this->setJson('CountDrafts', $CountDrafts); } } } elseif ($this->Request->isPostBack()) { throw new Gdn_UserException(t('Invalid CSRF token.', 'Invalid CSRF token. Please try again.'), 401); } else { // Load form if (isset($this->Comment)) { $this->Form->setData((array) $this->Comment); } } // Include data for FireEvent if (property_exists($this, 'Discussion')) { $this->EventArguments['Discussion'] = $this->Discussion; } if (property_exists($this, 'Comment')) { $this->EventArguments['Comment'] = $this->Comment; } $this->fireEvent('BeforeCommentRender'); if ($this->deliveryType() == DELIVERY_TYPE_DATA) { if ($this->data('Comments') instanceof Gdn_DataSet) { $Comment = $this->data('Comments')->firstRow(DATASET_TYPE_ARRAY); if ($Comment) { $Photo = $Comment['InsertPhoto']; if (strpos($Photo, '//') === false) { $Photo = Gdn_Upload::url(changeBasename($Photo, 'n%s')); } $Comment['InsertPhoto'] = $Photo; } $this->Data = array('Comment' => $Comment); } $this->RenderData($this->Data); } else { require_once $this->fetchViewLocation('helper_functions', 'Discussion'); // Render default view. $this->render(); } }
?> " class="Item"> <?php $this->fireEvent('BeforeItemContent'); ?> <div class="ItemContent"> <div class="Message"><?php echo SliceString(Gdn_Format::text(Gdn_Format::to($Comment->Body, $Comment->Format), false), 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 echo anchor(Gdn_Format::date($Comment->DateInserted), $Permalink); ?> </span> </div> </div> </li> <?php }
echo $Class == '' ? '' : ' class="' . $Class . '"'; ?> > <div id="Item_<?php echo $CurrentOffset; ?> " class="ConversationMessage"> <div class="Meta"> <span class="Author"> <?php echo userPhoto($Author, 'Photo'); echo userAnchor($Author, 'Name'); ?> </span> <span class="MItem DateCreated"><?php echo Gdn_Format::date($Message->DateInserted, 'html'); ?> </span> <?php $this->fireEvent('AfterConversationMessageDate'); ?> </div> <div class="Message"> <?php $this->fireEvent('BeforeConversationMessageBody'); echo Gdn_Format::to($Message->Body, $Format); $this->EventArguments['Message'] =& $Message; $this->fireEvent('AfterConversationMessageBody'); ?> </div> </div>
if ($LastPhoto) { echo '<div class="Author Photo">' . $LastPhoto . '</div>'; } echo anchor(htmlspecialchars($Names), $Url); } if ($Subject = val('Subject', $Conversation)) { if ($Names) { echo Bullet(' '); } echo '<span class="Subject">' . anchor(htmlspecialchars($Subject), $Url) . '</span>'; } echo '</h3>'; ?> <div class="Excerpt"><?php echo anchor(htmlspecialchars($Message), $Url, 'Message'); ?> </div> <div class="Meta"> <?php $this->fireEvent('BeforeConversationMeta'); echo ' <span class="MItem CountMessages">' . sprintf(Plural($Conversation->CountMessages, '%s message', '%s messages'), $Conversation->CountMessages) . '</span> '; if ($Conversation->CountNewMessages > 0) { echo ' <strong class="HasNew"> ' . plural($Conversation->CountNewMessages, '%s new', '%s new') . '</strong> '; } echo ' <span class="MItem LastDateInserted">' . Gdn_Format::date($Conversation->LastDateInserted) . '</span> '; ?> </div> </div> </li> <?php }
function writeActivityComment($Comment, $Activity) { $Session = Gdn::session(); $Author = UserBuilder($Comment, 'Insert'); $PhotoAnchor = userPhoto($Author, 'Photo'); $CssClass = 'Item ActivityComment ActivityComment'; if ($PhotoAnchor != '') { $CssClass .= ' HasPhoto'; } ?> <li id="ActivityComment_<?php echo $Comment['ActivityCommentID']; ?> " class="<?php echo $CssClass; ?> "> <?php if ($PhotoAnchor != '') { ?> <div class="Author Photo"><?php echo $PhotoAnchor; ?> </div> <?php } ?> <div class="ItemContent ActivityComment"> <?php echo userAnchor($Author, 'Title Name'); ?> <div class="Excerpt"><?php echo Gdn_Format::to($Comment['Body'], $Comment['Format']); ?> </div> <div class="Meta"> <span class="DateCreated"><?php echo Gdn_Format::date($Comment['DateInserted'], 'html'); ?> </span> <?php if (ActivityModel::canDelete($Activity)) { echo anchor(t('Delete'), "dashboard/activity/deletecomment?id={$Comment['ActivityCommentID']}&tk=" . $Session->TransientKey() . '&target=' . urlencode(Gdn_Url::Request()), 'DeleteComment'); } ?> </div> </div> </li> <?php }
$PhotoAnchor = anchor(img($Activity['Photo'], array('class' => 'ProfilePhoto PhotoWrapMedium')), $Activity['PhotoUrl'], 'PhotoWrap PhotoWrapMedium'); } else { $PhotoAnchor = ''; } ?> <div class="Author Photo"><?php echo $PhotoAnchor; ?> </div> <div class="ItemContent Activity"> <?php echo $Activity['Headline']; ?> <div class="Meta"> <span class="MItem DateCreated"><?php echo Gdn_Format::date($Activity['DateUpdated']); ?> </span> </div> </div> </li> <?php } ?> <li class="Item Center"> <?php echo anchor(sprintf(t('All %s'), t('Notifications')), '/profile/notifications'); ?> </li> <?php } else {
<?php if (!defined('APPLICATION')) { exit; } $Loop = 1; echo '<div class="Feed">'; foreach ($this->Feed->channel->item as $Item) { if ($Loop > $this->MaxLength) { break; } $Title = val('title', $Item); $Link = val('link', $Item); $PubDate = strtotime(val('pubDate', $Item)); if ($this->FeedFormat == 'extended') { $Description = val('description', $Item); // Cut off after the first subheading. $Description = array_shift(explode('<h', $Description)); echo wrap(wrap(anchor($Title, $Link), 'h2') . wrap(Gdn_Format::date($PubDate), 'div', ['class' => 'Date']) . wrap($Description, 'div', ['class' => 'FeedDescription']), 'div', ['class' => 'FeedItem ExtendedFormat']); } else { echo wrap('<span class="Sprite SpriteRarr SpriteRarrDown">→</span>' . anchor($Title, $Link) . wrap(Gdn_Format::date($PubDate), 'div', ['class' => 'Date']), 'div', ['class' => 'FeedItem NormalFormat']); } $Loop++; } echo '</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 } ?> <li class="Item Center"> <?php echo anchor(sprintf(t('All %s'), t('Messages')), '/messages/inbox'); ?> </li> <?php } else { ?>
} } // Only make a blockquote if we got a reason. if ($User->DiscoveryText) { echo Gdn_Format::text($User->DiscoveryText); } // Opportunity for plugins to do arbitrary appending. $this->fireEvent("AppendApplicantInfo"); ?> </td> <td><?php echo ipAnchor($User->InsertIPAddress); ?> </td> <td><?php echo Gdn_Format::date($User->DateInserted); ?> </td> <td class="options"> <div class="btn-group"> <?php echo anchor(dashboardSymbol('checkmark'), '/user/approve/' . $User->UserID, 'ApproveApplicant btn btn-icon', ['aria-label' => t('Approve'), 'title' => t('Approve')]); echo anchor(dashboardSymbol('delete'), '/user/decline/' . $User->UserID . '/' . $Session->TransientKey(), 'DeclineApplicant btn btn-icon', ['aria-label' => t('Decline'), 'title' => t('Decline')]); ?> </div> </td> </tr> <?php } ?> </tbody>
<div class="ItemContent Category"><div class="Options">' . getOptions($Category, $this) . '</div>' . Gdn_Format::text($Category->Name) . '</div> </li>'; $Alt = FALSE; } else { $LastComment = UserBuilder($Category, 'Last'); $AltCss = $Alt ? ' Alt' : ''; $Alt = !$Alt; $CatList .= '<li id="Category_' . $CategoryID . '" class="' . $CssClass . '"> <div class="ItemContent Category">' . '<div class="Options">' . getOptions($Category, $this) . '</div>' . CategoryPhoto($Category) . '<div class="TitleWrap">' . anchor(Gdn_Format::text($Category->Name), CategoryUrl($Category), 'Title') . '</div> <div class="CategoryDescription">' . $Category->Description . '</div> <div class="Meta"> <span class="MItem RSS">' . anchor(img('applications/dashboard/design/images/rss.gif', array('alt' => T('RSS Feed'))), '/categories/' . $Category->UrlCode . '/feed.rss', '', array('title' => T('RSS Feed'))) . '</span> <span class="MItem DiscussionCount">' . sprintf(PluralTranslate($Category->CountDiscussions, '%s discussion html', '%s discussions html', t('%s discussion'), t('%s discussions')), BigPlural($Category->CountDiscussions, '%s discussion')) . '</span> <span class="MItem CommentCount">' . sprintf(PluralTranslate($Category->CountComments, '%s comment html', '%s comments html', t('%s comment'), t('%s comments')), BigPlural($Category->CountComments, '%s comment')) . '</span>'; if ($Category->LastTitle != '') { $CatList .= '<span class="MItem LastDiscussionTitle">' . sprintf(t('Most recent: %1$s by %2$s'), anchor(Gdn_Format::text(sliceString($Category->LastTitle, 40)), $Category->LastUrl), userAnchor($LastComment)) . '</span>' . '<span class="MItem LastCommentDate">' . Gdn_Format::date($Category->LastDateInserted) . '</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.
?> </th> </tr> </thead> <tbody> <?php foreach ($this->UserData->Format('Text')->result() as $User) { ?> <tr> <td><?php echo $this->Form->CheckBox('Applicants[]', '', array('value' => $User->UserID)); ?> </td> <td class="Alt"> <?php printf(t('<strong>%1$s</strong> (%2$s) %3$s'), $User->Name, Gdn_Format::Email($User->Email), Gdn_Format::date($User->DateInserted)); $this->EventArguments['User'] = $User; $this->fireEvent("ApplicantInfo"); echo '<blockquote>' . $User->DiscoveryText . '</blockquote>'; $this->EventArguments['User'] = $User; $this->fireEvent("AppendApplicantInfo"); ?> </td> <td><?php echo anchor(t('Approve'), '/user/approve/' . $User->UserID . '/' . $Session->TransientKey()) . ' ' . anchor(t('Decline'), '/user/decline/' . $User->UserID . '/' . $Session->TransientKey()); ?> </td> </tr> <?php } ?>
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 = val('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('', ' ')) . anchor($DiscussionName, $DiscussionUrl); $Sender->fireEvent('AfterDiscussionTitle'); ?> </div> <div class="Meta Meta-Discussion"> <?php WriteTags($Discussion); ?> <span class="MItem MCount ViewCount"><?php printf(PluralTranslate($Discussion->CountViews, '%s view html', '%s views html', t('%s view'), t('%s views')), BigPlural($Discussion->CountViews, '%s view')); ?> </span> <span class="MItem MCount CommentCount"><?php printf(PluralTranslate($Discussion->CountComments, '%s comment html', '%s comments html', t('%s comment'), t('%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> <?php echo NewComments($Discussion); $Sender->fireEvent('AfterCountMeta'); if ($Discussion->LastCommentID != '') { echo ' <span class="MItem LastCommentBy">' . sprintf(t('Most recent by %1$s'), userAnchor($Last)) . '</span> '; echo ' <span class="MItem LastCommentDate">' . Gdn_Format::date($Discussion->LastDate, 'html') . '</span>'; } else { echo ' <span class="MItem LastCommentBy">' . sprintf(t('Started by %1$s'), userAnchor($First)) . '</span> '; echo ' <span class="MItem LastCommentDate">' . Gdn_Format::date($Discussion->FirstDate, 'html'); if ($Source = val('Source', $Discussion)) { echo ' ' . sprintf(t('via %s'), t($Source . ' Source', $Source)); } echo '</span> '; } if ($Sender->data('_ShowCategoryLink', true) && c('Vanilla.Categories.Use') && $Category) { echo wrap(Anchor(htmlspecialchars($Discussion->Category), CategoryUrl($Discussion->CategoryUrlCode)), 'span', array('class' => 'MItem Category ' . $Category['CssClass'])); } $Sender->fireEvent('DiscussionMeta'); ?> </div> </div> <?php $Sender->fireEvent('AfterDiscussionContent'); ?> </li> <?php }
/** * Set the date range. * * @param $Sender * @throws Exception */ private function configureRange($Sender) { // Grab the range resolution from the url or form. Default to "day" range. $Sender->Range = getIncomingValue('Range'); if (!in_array($Sender->Range, array(VanillaStatsPlugin::RESOLUTION_DAY, VanillaStatsPlugin::RESOLUTION_MONTH))) { $Sender->Range = VanillaStatsPlugin::RESOLUTION_DAY; } // Define default values for start & end dates $Sender->DayStampStart = strtotime('1 month ago'); // Default to 1 month ago $Sender->MonthStampStart = strtotime('12 months ago'); // Default to 24 months ago $Sender->DayDateStart = Gdn_Format::toDate($Sender->DayStampStart); $Sender->MonthDateStart = Gdn_Format::toDate($Sender->MonthStampStart); // Validate that any values coming from the url or form are valid $Sender->DateRange = getIncomingValue('DateRange'); $DateRangeParts = explode('-', $Sender->DateRange); $Sender->StampStart = strtotime(val(0, $DateRangeParts)); $Sender->StampEnd = strtotime(val(1, $DateRangeParts)); if (!$Sender->StampEnd) { $Sender->StampEnd = strtotime('yesterday'); } // If no date was provided, or the provided values were invalid, use defaults if (!$Sender->StampStart) { $Sender->StampEnd = time(); if ($Sender->Range == 'day') { $Sender->StampStart = $Sender->DayStampStart; } if ($Sender->Range == 'month') { $Sender->StampStart = $Sender->MonthStampStart; } } // Assign the variables used in the page with the validated values. $Sender->DateStart = Gdn_Format::toDate($Sender->StampStart); $Sender->DateEnd = Gdn_Format::toDate($Sender->StampEnd); $Sender->DateRange = $Sender->DateStart . ' - ' . $Sender->DateEnd; // Define the range boundaries. $Database = Gdn::database(); // We use the User table as the boundary start b/c users are always inserted before discussions or comments. // We have to put a little kludge in here b/c an older version of Vanilla hard-inserted the admin user with an insert date of Sept 16, 1975. $Data = $Database->sql()->select('DateInserted')->from('User')->where('DateInserted >', '1975-09-17')->orderBy('DateInserted', 'asc')->limit(1)->get()->firstRow(); $Sender->BoundaryStart = Gdn_Format::date($Data ? $Data->DateInserted : $Sender->DateStart, '%Y-%m-%d'); $Sender->BoundaryEnd = Gdn_Format::date($Sender->DateEnd, '%Y-%m-%d'); }
</div> <div class="ItemContent"> <b class="Subject"><?php echo anchor($Row->Name, $Row->Url . '#latest'); ?> </b> <div class="Meta"> <?php echo ' <span class="MItem">' . plural($Row->CountComments, '%s comment', '%s comments') . '</span> '; if ($Row->CountUnreadComments === TRUE) { echo ' <strong class="HasNew"> ' . t('new') . '</strong> '; } elseif ($Row->CountUnreadComments > 0) { echo ' <strong class="HasNew"> ' . plural($Row->CountUnreadComments, '%s new', '%s new plural') . '</strong> '; } echo ' <span class="MItem">' . Gdn_Format::date($Row->DateLastComment) . '</span> '; ?> </div> </div> </li> <?php } ?> <li class="Item Center"> <?php echo anchor(sprintf(t('All %s'), t('Bookmarks')), '/discussions/bookmarked'); ?> </li> <?php } else { ?>
function writeComment($Comment, $Sender, $Session, $CurrentOffset) { static $UserPhotoFirst = NULL; if ($UserPhotoFirst === null) { $UserPhotoFirst = c('Vanilla.Comment.UserPhotoFirst', true); } $Author = Gdn::userModel()->getID($Comment->InsertUserID); //UserBuilder($Comment, 'Insert'); $Permalink = val('Url', $Comment, '/discussion/comment/' . $Comment->CommentID . '/#Comment_' . $Comment->CommentID); // Set CanEditComments (whether to show checkboxes) if (!property_exists($Sender, 'CanEditComments')) { $Sender->CanEditComments = $Session->checkPermission('Vanilla.Comments.Edit', TRUE, 'Category', 'any') && c('Vanilla.AdminCheckboxes.Use'); } // Prep event args $CssClass = CssClass($Comment, $CurrentOffset); $Sender->EventArguments['Comment'] =& $Comment; $Sender->EventArguments['Author'] =& $Author; $Sender->EventArguments['CssClass'] =& $CssClass; $Sender->EventArguments['CurrentOffset'] = $CurrentOffset; $Sender->EventArguments['Permalink'] = $Permalink; // DEPRECATED ARGUMENTS (as of 2.1) $Sender->EventArguments['Object'] =& $Comment; $Sender->EventArguments['Type'] = 'Comment'; // First comment template event $Sender->fireEvent('BeforeCommentDisplay'); ?> <li class="<?php echo $CssClass; ?> " id="<?php echo 'Comment_' . $Comment->CommentID; ?> "> <div class="Comment"> <?php // Write a stub for the latest comment so it's easy to link to it from outside. if ($CurrentOffset == Gdn::controller()->data('_LatestItem')) { echo '<span id="latest"></span>'; } ?> <div class="Options"> <?php WriteCommentOptions($Comment); ?> </div> <?php $Sender->fireEvent('BeforeCommentMeta'); ?> <div class="Item-Header CommentHeader"> <div class="AuthorWrap"> <span class="Author"> <?php if ($UserPhotoFirst) { echo userPhoto($Author); echo userAnchor($Author, 'Username'); } else { echo userAnchor($Author, 'Username'); echo userPhoto($Author); } echo FormatMeAction($Comment); $Sender->fireEvent('AuthorPhoto'); ?> </span> <span class="AuthorInfo"> <?php echo ' ' . WrapIf(htmlspecialchars(val('Title', $Author)), 'span', array('class' => 'MItem AuthorTitle')); echo ' ' . WrapIf(htmlspecialchars(val('Location', $Author)), 'span', array('class' => 'MItem AuthorLocation')); $Sender->fireEvent('AuthorInfo'); ?> </span> </div> <div class="Meta CommentMeta CommentInfo"> <span class="MItem DateCreated"> <?php echo anchor(Gdn_Format::date($Comment->DateInserted, 'html'), $Permalink, 'Permalink', array('name' => 'Item_' . $CurrentOffset, 'rel' => 'nofollow')); ?> </span> <?php echo DateUpdated($Comment, array('<span class="MItem">', '</span>')); ?> <?php // Include source if one was set if ($Source = val('Source', $Comment)) { echo wrap(sprintf(t('via %s'), t($Source . ' Source', $Source)), 'span', array('class' => 'MItem Source')); } $Sender->fireEvent('CommentInfo'); $Sender->fireEvent('InsideCommentMeta'); // DEPRECATED $Sender->fireEvent('AfterCommentMeta'); // DEPRECATED // Include IP Address if we have permission if ($Session->checkPermission('Garden.PersonalInfo.View')) { echo wrap(IPAnchor($Comment->InsertIPAddress), 'span', array('class' => 'MItem IPAddress')); } ?> </div> </div> <div class="Item-BodyWrap"> <div class="Item-Body"> <div class="Message"> <?php echo FormatBody($Comment); ?> </div> <?php $Sender->fireEvent('AfterCommentBody'); WriteReactions($Comment); if (val('Attachments', $Comment)) { WriteAttachments($Comment->Attachments); } ?> </div> </div> </div> </li> <?php $Sender->fireEvent('AfterComment'); }
if ($User->Admin > 1) { $RolesString = concatSep(', ', $RolesString, t('System')); } foreach ($Roles as $RoleID => $RoleName) { $Query = http_build_query(array('Keywords' => $RoleName)); $RolesString = concatSep(', ', $RolesString, '<a href="' . url('/user/browse?' . $Query) . '">' . htmlspecialchars($RoleName) . '</a>'); } echo $RolesString; ?> </td> <td class="Alt"><?php echo Gdn_Format::date($User->DateFirstVisit, 'html'); ?> </td> <td><?php echo Gdn_Format::date($User->DateLastActive, 'html'); ?> </td> <?php if ($ViewPersonalInfo) { ?> <td><?php echo formatIP($User->LastIPAddress); ?> </td> <?php } ?> <?php $this->EventArguments['User'] = $User; $this->fireEvent('UserCell');
} echo formatMeAction($Discussion); ?> </span> <span class="AuthorInfo"> <?php echo wrapIf(htmlspecialchars(val('Title', $Author)), 'span', array('class' => 'MItem AuthorTitle')); echo wrapIf(htmlspecialchars(val('Location', $Author)), 'span', array('class' => 'MItem AuthorLocation')); $this->fireEvent('AuthorInfo'); ?> </span> </div> <div class="Meta DiscussionMeta"> <span class="MItem DateCreated"> <?php echo anchor(Gdn_Format::date($Discussion->DateInserted, 'html'), $Discussion->Url, 'Permalink', array('rel' => 'nofollow')); ?> </span> <?php echo dateUpdated($Discussion, array('<span class="MItem">', '</span>')); ?> <?php // Include source if one was set if ($Source = val('Source', $Discussion)) { echo ' ' . wrap(sprintf(t('via %s'), t($Source . ' Source', $Source)), 'span', array('class' => 'MItem MItem-Source')) . ' '; } // Category if (c('Vanilla.Categories.Use')) { echo ' <span class="MItem Category">'; echo ' ' . t('in') . ' '; echo anchor(htmlspecialchars($this->data('Discussion.Category')), categoryUrl($this->data('Discussion.CategoryUrlCode')));
$TagCount = $this->data('RecordCount'); $Tags = $this->data('Tags'); ?> <tbody> <?php foreach ($Tags as $Tag) { $CssClass = 'TagAdmin'; $Title = ''; $Special = FALSE; $type = val('Type', $Tag); if (empty($type)) { $type = t('Tag'); } $userModel = new UserModel(); $createdBy = $userModel->getID(val('InsertUserID', $Tag)); $dateInserted = Gdn_Format::date(val('DateInserted', $Tag), '%e %b %Y'); $count = val('CountDiscussions', $Tag, 0); $displayName = TagFullName($Tag); if (val('Type', $Tag)) { $Special = TRUE; $CssClass .= " Tag-Special Tag-{$Tag['Type']}"; $Title = t('This is a special tag.'); } ?> <tr id="<?php echo "Tag_{$Tag['TagID']}"; ?> " class="<?php echo $CssClass; ?> "
?> </h3> <div class="Item-Body Media"> <?php $Photo = userPhoto($Row, array('LinkClass' => 'Img')); if ($Photo) { echo $Photo; } ?> <div class="Media-Body"> <div class="Meta"> <?php echo ' <span class="MItem-Author">' . sprintf(t('by %s'), userAnchor($Row)) . '</span>'; echo Bullet(' '); echo ' <span clsss="MItem-DateInserted">' . Gdn_Format::date($Row['DateInserted'], 'html') . '</span> '; if (isset($Row['Breadcrumbs'])) { echo Bullet(' '); echo ' <span class="MItem-Location">' . Gdn_Theme::Breadcrumbs($Row['Breadcrumbs'], false) . '</span> '; } if (isset($Row['Notes'])) { echo ' <span class="Aside Debug">debug(' . $Row['Notes'] . ')</span>'; } ?> </div> <div class="Summary"> <?php echo $Row['Summary']; ?> </div> <?php
function dateUpdated($Row, $Wrap = null) { $Result = ''; $DateUpdated = val('DateUpdated', $Row); $UpdateUserID = val('UpdateUserID', $Row); if ($DateUpdated) { $UpdateUser = Gdn::userModel()->getID($UpdateUserID); if ($UpdateUser) { $Title = sprintf(T('Edited %s by %s.'), Gdn_Format::dateFull($DateUpdated), val('Name', $UpdateUser)); } else { $Title = sprintf(T('Edited %s.'), Gdn_Format::dateFull($DateUpdated)); } $Result = ' <span title="' . htmlspecialchars($Title) . '" class="DateUpdated">' . sprintf(T('edited %s'), Gdn_Format::date($DateUpdated)) . '</span> '; if ($Wrap) { $Result = $Wrap[0] . $Result . $Wrap[1]; } } return $Result; }
/** * Formats a date. * * @see Gdn_Format::Date() */ function smarty_modifier_date($Date, $Format = '') { return Gdn_Format::date($Date, $Format); }
/** * 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 } }
if ($Row['RecordName']) { echo ' <span class="Meta">', '<span class="Meta-Label">' . sprintf(t('%s by'), t($RecordLabel)) . '</span> ', userAnchor($Row, 'Meta-Value', 'Record'); if ($RecordUser['Banned']) { echo ' <span class="Tag Tag-Ban">' . t('Banned') . '</span>'; } echo ' <span class="Count">' . plural($RecordUser['CountDiscussions'] + $RecordUser['CountComments'], '%s post', '%s posts') . '</span>'; echo '</span> '; } // Write custom meta information. $CustomMeta = valr('Data._Meta', $Row, false); if (is_array($CustomMeta)) { foreach ($CustomMeta as $Key => $Value) { echo ' <span class="Meta">', '<span class="Meta-Label">' . t($Key) . '</span> ', wrap(Gdn_Format::Html($Value), 'span', array('class' => 'Meta-Value')), '</span>'; } } echo '</div>'; ?> </td> <td class="DateCell"><?php echo Gdn_Format::date($Row['DateInserted'], 'html'); ?> </td> </tr> <?php } ?> </tbody> </table> <?php PagerModule::write();