public function Choose($AuthenticationSchemeAlias = NULL) { $this->Permission('Garden.Settings.Manage'); $this->AddSideMenu('dashboard/authentication'); $this->Title(T('Authentication')); $this->AddCssFile('authentication.css'); $PreFocusAuthenticationScheme = NULL; if (!is_null($AuthenticationSchemeAlias)) { $PreFocusAuthenticationScheme = $AuthenticationSchemeAlias; } if ($this->Form->AuthenticatedPostback()) { $NewAuthSchemeAlias = $this->Form->GetValue('Garden.Authentication.Chooser'); $AuthenticatorInfo = Gdn::Authenticator()->GetAuthenticatorInfo($NewAuthSchemeAlias); if ($AuthenticatorInfo !== FALSE) { $CurrentAuthenticatorAlias = Gdn::Authenticator()->AuthenticateWith('default')->GetAuthenticationSchemeAlias(); // Disable current $AuthenticatorDisableEvent = "DisableAuthenticator" . ucfirst($CurrentAuthenticatorAlias); $this->FireEvent($AuthenticatorDisableEvent); // Enable new $AuthenticatorEnableEvent = "EnableAuthenticator" . ucfirst($NewAuthSchemeAlias); $this->FireEvent($AuthenticatorEnableEvent); $PreFocusAuthenticationScheme = $NewAuthSchemeAlias; $this->CurrentAuthenticationAlias = Gdn::Authenticator()->AuthenticateWith('default')->GetAuthenticationSchemeAlias(); } } $this->SetData('AuthenticationConfigureList', json_encode($this->ConfigureList)); $this->SetData('PreFocusAuthenticationScheme', $PreFocusAuthenticationScheme); $this->Render(); }
/** * * @param Gdn_Controller $Sender * @throws Exception */ public function __construct($Sender = null) { if (property_exists($Sender, 'Conversation')) { $this->Conversation = $Sender->Conversation; } // Allowed to use this module? $this->AddUserAllowed = $Sender->ConversationModel->addUserAllowed($this->Conversation->ConversationID); $this->Form = Gdn::factory('Form', 'AddPeople'); // If the form was posted back, check for people to add to the conversation if ($this->Form->authenticatedPostBack()) { // Defer exceptions until they try to use the form so we don't fill our logs if (!$this->AddUserAllowed || !checkPermission('Conversations.Conversations.Add')) { throw permissionException(); } $NewRecipientUserIDs = array(); $NewRecipients = explode(',', $this->Form->getFormValue('AddPeople', '')); $UserModel = Gdn::factory("UserModel"); foreach ($NewRecipients as $Name) { if (trim($Name) != '') { $User = $UserModel->getByUsername(trim($Name)); if (is_object($User)) { $NewRecipientUserIDs[] = $User->UserID; } } } $Sender->ConversationModel->addUserToConversation($this->Conversation->ConversationID, $NewRecipientUserIDs); $Sender->informMessage(t('Your changes were saved.')); $Sender->RedirectUrl = url('/messages/' . $this->Conversation->ConversationID); } $this->_ApplicationFolder = $Sender->Application; $this->_ThemeFolder = $Sender->Theme; }
/** * 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(); }
public function Index($Offset = 0, $Limit = NULL) { $this->AddJsFile('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'); $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) { $ResultSet = array(); } $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(); }
public function NotSpam($LogIDs) { $this->Permission('Garden.Moderation.Manage'); if (!$this->Request->IsPostBack()) { throw PermissionException('Javascript'); } $Logs = array(); // Verify the appropriate users. $UserIDs = $this->Form->GetFormValue('UserID', array()); if (!is_array($UserIDs)) { $UserIDs = array(); } foreach ($UserIDs as $UserID) { Gdn::UserModel()->SetField($UserID, 'Verified', TRUE); $Logs = array_merge($Logs, $this->LogModel->GetWhere(array('Operation' => 'Spam', 'RecordUserID' => $UserID))); } // Grab the logs. $Logs = array_merge($Logs, $this->LogModel->GetIDs($LogIDs)); // try { foreach ($Logs as $Log) { $this->LogModel->Restore($Log); } // } catch (Exception $Ex) { // $this->Form->AddError($Ex->getMessage()); // } $this->LogModel->Recalculate(); $this->SetData('Complete'); $this->SetData('Count', count($Logs)); $this->Render('Blank', 'Utility'); }
/** * Select Authentication method. * * @since 2.0.3 * @access public * * @param string $AuthenticationSchemeAlias */ public function choose($AuthenticationSchemeAlias = null) { $this->permission('Garden.Settings.Manage'); $this->addSideMenu('dashboard/authentication'); $this->title(t('Authentication')); $this->addCssFile('authentication.css'); $PreFocusAuthenticationScheme = null; if (!is_null($AuthenticationSchemeAlias)) { $PreFocusAuthenticationScheme = $AuthenticationSchemeAlias; } if ($this->Form->authenticatedPostback()) { $NewAuthSchemeAlias = $this->Form->getValue('Garden.Authentication.Chooser'); $AuthenticatorInfo = Gdn::authenticator()->getAuthenticatorInfo($NewAuthSchemeAlias); if ($AuthenticatorInfo !== false) { $CurrentAuthenticatorAlias = Gdn::authenticator()->AuthenticateWith('default')->getAuthenticationSchemeAlias(); // Disable current $AuthenticatorDisableEvent = "DisableAuthenticator" . ucfirst($CurrentAuthenticatorAlias); $this->fireEvent($AuthenticatorDisableEvent); // Enable new $AuthenticatorEnableEvent = "EnableAuthenticator" . ucfirst($NewAuthSchemeAlias); $this->fireEvent($AuthenticatorEnableEvent); $PreFocusAuthenticationScheme = $NewAuthSchemeAlias; $this->CurrentAuthenticationAlias = Gdn::authenticator()->authenticateWith('default')->getAuthenticationSchemeAlias(); } } $this->setData('AuthenticationConfigureList', $this->ConfigureList); $this->setData('PreFocusAuthenticationScheme', $PreFocusAuthenticationScheme); $this->render(); }
public function notSpam() { if (!Gdn::request()->isAuthenticatedPostBack(true)) { throw new Exception('Requires POST', 405); } $this->permission(array('Garden.Moderation.Manage', 'Moderation.Spam.Manage'), false); $LogIDs = Gdn::request()->post('LogIDs'); $Logs = array(); // Verify the appropriate users. $UserIDs = $this->Form->getFormValue('UserID', array()); if (!is_array($UserIDs)) { $UserIDs = array(); } foreach ($UserIDs as $UserID) { Gdn::userModel()->setField($UserID, 'Verified', true); $Logs = array_merge($Logs, $this->LogModel->getWhere(array('Operation' => 'Spam', 'RecordUserID' => $UserID))); } // Grab the logs. $Logs = array_merge($Logs, $this->LogModel->getIDs($LogIDs)); // try { foreach ($Logs as $Log) { $this->LogModel->restore($Log); } // } catch (Exception $Ex) { // $this->Form->addError($Ex->getMessage()); // } $this->LogModel->recalculate(); $this->setData('Complete'); $this->setData('Count', count($Logs)); $this->render('Blank', 'Utility'); }
public function RemoveAddon($Type, $Name, $TransientKey = '') { $RequiredPermission = 'Undefined'; switch ($Type) { case SettingsModule::TYPE_APPLICATION: $Manager = Gdn::Factory('ApplicationManager'); $Enabled = 'EnabledApplications'; $Remove = 'RemoveApplication'; $RequiredPermission = 'Garden.Applications.Manage'; break; case SettingsModule::TYPE_PLUGIN: $Manager = Gdn::Factory('PluginManager'); $Enabled = 'EnabledPlugins'; $Remove = 'RemovePlugin'; $RequiredPermission = 'Garden.Plugins.Manage'; break; } $Session = Gdn::Session(); if ($Session->ValidateTransientKey($TransientKey) && $Session->CheckPermission($RequiredPermission)) { try { if (array_key_exists($Name, $Manager->{$Enabled}) === FALSE) { $Manager->{$Remove}($Name); } } catch (Exception $e) { $this->Form->AddError(strip_tags($e->getMessage())); } } if ($this->Form->ErrorCount() == 0) { Redirect('/settings/plugins'); } }
/** * * @param Gdn_Form $Sender */ public function Gdn_Form_BeforeBodyBox_Handler($Sender, $Args) { $Column = GetValue('Column', $Args, 'Body'); $this->_AddCLEditor(Gdn::Controller(), $Column); $Format = $Sender->GetValue('Format'); if ($Format) { $Formatter = Gdn::Factory($Format . 'Formatter'); if ($Formatter && method_exists($Formatter, 'FormatForWysiwyg')) { $Body = $Formatter->FormatForWysiwyg($Sender->GetValue($Column)); $Sender->SetValue($Column, $Body); } elseif (!in_array($Format, array('Html', 'Wysiwyg'))) { $Sender->SetValue($Column, Gdn_Format::To($Sender->GetValue($Column), $Format)); } } $Sender->SetValue('Format', 'Wysiwyg'); }
/** * Enabling and disabling categories from list. * * @since 2.0.0 * @access public */ public function ManageCategories() { // Check permission $this->Permission('Garden.Settings.Manage'); $this->AddSideMenu('vanilla/settings/managecategories'); $this->AddJsFile('categories.js'); $this->AddJsFile('js/library/jquery.alphanumeric.js'); // This now works on latest jQuery version 1.10.2 // // Jan29, 2014, upgraded jQuery UI to 1.10.3 from 1.8.11 $this->AddJsFile('js/library/nestedSortable/jquery-ui.min.js'); // Newer nestedSortable, but does not work. //$this->AddJsFile('js/library/nestedSortable/jquery.mjs.nestedSortable.js'); // old jquery-ui //$this->AddJsFile('js/library/nestedSortable.1.3.4/jquery-ui-1.8.11.custom.min.js'); $this->AddJsFile('js/library/nestedSortable.1.3.4/jquery.ui.nestedSortable.js'); $this->Title(T('Categories')); // Get category data $this->SetData('CategoryData', $this->CategoryModel->GetAll('TreeLeft'), TRUE); // Enable/Disable Categories if (Gdn::Session()->ValidateTransientKey(GetValue(1, $this->RequestArgs))) { $Toggle = GetValue(0, $this->RequestArgs, ''); if ($Toggle == 'enable') { SaveToConfig('Vanilla.Categories.Use', TRUE); } else { if ($Toggle == 'disable') { SaveToConfig('Vanilla.Categories.Use', FALSE); } } Redirect('vanilla/settings/managecategories'); } // Setup & save forms $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigurationModel->SetField(array('Vanilla.Categories.MaxDisplayDepth', 'Vanilla.Categories.DoHeadings', 'Vanilla.Categories.HideModule')); // Set the model on the form. $this->Form->SetModel($ConfigurationModel); // Define MaxDepthOptions $DepthData = array(); $DepthData['2'] = sprintf(T('more than %s deep'), Plural(1, '%s level', '%s levels')); $DepthData['3'] = sprintf(T('more than %s deep'), Plural(2, '%s level', '%s levels')); $DepthData['4'] = sprintf(T('more than %s deep'), Plural(3, '%s level', '%s levels')); $DepthData['0'] = T('never'); $this->SetData('MaxDepthData', $DepthData); // If seeing the form for the first time... if ($this->Form->AuthenticatedPostBack() === FALSE) { // Apply the config settings to the form. $this->Form->SetData($ConfigurationModel->Data); } else { if ($this->Form->Save() !== FALSE) { $this->InformMessage(T("Your settings have been saved.")); } } // Render default view $this->Render(); }
/** * Edit a comment (wrapper for PostController::Comment). * * Will throw an error if both params are blank. * * @since 2.0.0 * @access public * * @param int $CommentID Unique ID of the comment to edit. * @param int $DraftID Unique ID of the draft to edit. */ public function EditComment($CommentID = '', $DraftID = '') { if (is_numeric($CommentID) && $CommentID > 0) { $this->Form->SetModel($this->CommentModel); $this->Comment = $this->CommentModel->GetID($CommentID); } else { $this->Form->SetModel($this->DraftModel); $this->Comment = $this->DraftModel->GetID($DraftID); } $this->View = 'Comment'; $this->Comment($this->Comment->DiscussionID); }
/** * Look for users with an invalid role and apply the role specified to those users. */ public function fixUserRole() { $this->permission('Garden.Settings.Manage'); if ($this->Request->isAuthenticatedPostBack()) { if (validateRequired($this->Form->getFormValue('DefaultUserRole'))) { $this->Model->fixUserRole($this->Form->getFormValue('DefaultUserRole')); $this->setData('CompletedFix', true); } } $this->render(); }
function writeConditionEdit($Condition, $Sender) { $Px = $Sender->Prefix; $Form = new Gdn_Form(); $Type = val(0, $Condition, ''); $Field = val(1, $Condition, ''); $Expr = val(2, $Condition, ''); echo '<tr>'; // Type. echo '<td>', $Form->DropDown($Px . 'Type[]', $Sender->Types, array('Value' => $Type, 'Class' => 'CondType')), '</td>'; echo '<td>'; // Permission fields. echo '<div class="Cond_permission"' . _DN($Type, Gdn_Condition::PERMISSION) . '>', $Form->DropDown($Px . 'PermissionField[]', $Sender->Permissions, array('Value' => $Type == Gdn_Condition::PERMISSION ? $Field : '')), '</div>'; // Role fields. echo '<div class="Cond_role"' . _DN($Type, Gdn_Condition::ROLE) . '>', $Form->DropDown($Px . 'RoleField[]', $Sender->Roles, array('Value' => $Type == Gdn_Condition::ROLE ? $Field : '')), '</div>'; // Textbox field. echo '<div class="Cond_request"' . _DN($Type, Gdn_Condition::REQUEST) . '>', $Form->textBox($Px . 'Field[]', array('Value' => $Type == Gdn_Condition::REQUEST ? $Field : '')); '</div>'; echo '</td>'; // Expression. echo '<td>', '<div class="Cond_request"' . _DN($Type, Gdn_Condition::REQUEST) . '>', $Form->textBox($Px . 'Expr[]', array('Value' => $Type == Gdn_Condition::REQUEST ? $Expr : '')), '</div>', '</td>'; // Buttons. echo '<td align="right">', '<a href="#" class="DeleteCondition">', t('Delete'), '</a></td>'; echo '</tr>'; }
/** Grab the values from the form into the conditions array. */ protected function _FromForm() { $Form = new Gdn_Form(); $Px = $this->Prefix; $Types = (array) $Form->getFormValue($Px . 'Type', array()); $PermissionFields = (array) $Form->getFormValue($Px . 'PermissionField', array()); $RoleFields = (array) $Form->getFormValue($Px . 'RoleField', array()); $Fields = (array) $Form->getFormValue($Px . 'Field', array()); $Expressions = (array) $Form->getFormValue($Px . 'Expr', array()); $Conditions = array(); for ($i = 0; $i < count($Types) - 1; $i++) { $Condition = array($Types[$i]); switch ($Types[$i]) { case Gdn_Condition::PERMISSION: $Condition[1] = val($i, $PermissionFields, ''); break; case Gdn_Condition::REQUEST: $Condition[1] = val($i, $Fields, ''); $Condition[2] = val($i, $Expressions, ''); break; case Gdn_Condition::ROLE: $Condition[1] = val($i, $RoleFields); break; case '': $Condition[1] = ''; break; default: continue; } $Conditions[] = $Condition; } return $Conditions; }
/** * Set where to go after signin. * * @access public * @since 2.0.0 * * @param string $Target Where we're requested to go to. * @return string URL to actually go to (validated & safe). */ public function target($Target = false) { if ($Target === false) { $Target = $this->Form->getFormValue('Target', false); if (!$Target) { $Target = $this->Request->get('Target', '/'); } } // Make sure that the target is a valid url. if (!preg_match('`(^https?://)`', $Target)) { $Target = '/' . ltrim($Target, '/'); // Never redirect back to signin. if (preg_match('`^/entry/signin`i', $Target)) { $Target = '/'; } } else { $MyHostname = parse_url(Gdn::request()->domain(), PHP_URL_HOST); $TargetHostname = parse_url($Target, PHP_URL_HOST); // Only allow external redirects to trusted domains. $TrustedDomains = c('Garden.TrustedDomains', true); // Trusted domains were previously saved in config as an array. if ($TrustedDomains && $TrustedDomains !== true && !is_array($TrustedDomains)) { $TrustedDomains = explode("\n", $TrustedDomains); } if (is_array($TrustedDomains)) { // Add this domain to the trusted hosts. $TrustedDomains[] = $MyHostname; $this->EventArguments['TrustedDomains'] =& $TrustedDomains; $this->fireEvent('BeforeTargetReturn'); } if ($TrustedDomains === true) { return $Target; } elseif (count($TrustedDomains) == 0) { // Only allow http redirects if they are to the same host name. if ($MyHostname != $TargetHostname) { $Target = ''; } } else { // Loop the trusted domains looking for a match $Match = false; foreach ($TrustedDomains as $TrustedDomain) { if (stringEndsWith($TargetHostname, $TrustedDomain, true)) { $Match = true; } } if (!$Match) { $Target = ''; } } } return $Target; }
/** * Prompts new admins how to get started using new install. * * @since 2.0.0 * @access public */ public function gettingStarted() { $this->permission('Garden.Settings.Manage'); $this->setData('Title', t('Getting Started')); $this->addSideMenu('dashboard/settings/gettingstarted'); $this->TextEnterEmails = t('TextEnterEmails', 'Type email addresses separated by commas here'); if ($this->Form->authenticatedPostBack()) { // Do invitations to new members. $Message = $this->Form->getFormValue('InvitationMessage'); $Message = trim($Message); $Recipients = $this->Form->getFormValue('Recipients'); if ($Recipients == $this->TextEnterEmails) { $Recipients = ''; } $Recipients = explode(',', $Recipients); $CountRecipients = 0; foreach ($Recipients as $Recipient) { if (trim($Recipient) != '') { $CountRecipients++; if (!validateEmail($Recipient)) { $this->Form->addError(sprintf(t('%s is not a valid email address'), $Recipient)); } } } if ($CountRecipients == 0) { $this->Form->addError(t('You must provide at least one recipient')); } if ($this->Form->errorCount() == 0) { $Email = new Gdn_Email(); $Email->subject(t('Check out my new community!')); $emailTemplate = $Email->getEmailTemplate(); $emailTemplate->setMessage($Message, true)->setButton(externalUrl('/'), t('Check it out')); $Email->setEmailTemplate($emailTemplate); foreach ($Recipients as $Recipient) { if (trim($Recipient) != '') { $Email->to($Recipient); try { $Email->send(); } catch (Exception $ex) { $this->Form->addError($ex); } } } } if ($this->Form->errorCount() == 0) { $this->informMessage(t('Your invitations were sent successfully.')); } } $this->render(); }
/** * 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(); }
/** * Prompts new admins how to get started using new install. * * @since 2.0.0 * @access public */ public function GettingStarted() { $this->Permission('Garden.Settings.Manage'); $this->SetData('Title', T('Getting Started')); $this->AddSideMenu('dashboard/settings/gettingstarted'); $this->TextEnterEmails = T('TextEnterEmails', 'Type email addresses separated by commas here'); if ($this->Form->AuthenticatedPostBack()) { // Do invitations to new members. $Message = $this->Form->GetFormValue('InvitationMessage'); $Message .= "\n\n" . Gdn::Request()->Url('/', TRUE); $Message = trim($Message); $Recipients = $this->Form->GetFormValue('Recipients'); if ($Recipients == $this->TextEnterEmails) { $Recipients = ''; } $Recipients = explode(',', $Recipients); $CountRecipients = 0; foreach ($Recipients as $Recipient) { if (trim($Recipient) != '') { $CountRecipients++; if (!ValidateEmail($Recipient)) { $this->Form->AddError(sprintf(T('%s is not a valid email address'), $Recipient)); } } } if ($CountRecipients == 0) { $this->Form->AddError(T('You must provide at least one recipient')); } if ($this->Form->ErrorCount() == 0) { $Email = new Gdn_Email(); $Email->Subject(T('Check out my new community!')); $Email->Message($Message); foreach ($Recipients as $Recipient) { if (trim($Recipient) != '') { $Email->To($Recipient); try { $Email->Send(); } catch (Exception $ex) { $this->Form->AddError($ex); } } } } if ($this->Form->ErrorCount() == 0) { $this->InformMessage(T('Your invitations were sent successfully.')); } } $this->Render(); }
/** * Enable or disable the use of categories in Vanilla. * * @param bool $enabled Whether or not to enable/disable categories. * @throws Exception Throws an exception if accessed through an invalid post back. */ public function enableCategories($enabled) { $this->permission('Garden.Settings.Manage'); if ($this->Form->authenticatedPostBack()) { $enabled = (bool) $enabled; saveToConfig('Vanilla.Categories.Use', $enabled); $this->setData('Enabled', $enabled); if ($this->deliveryType() !== DELIVERY_TYPE_DATA) { $this->RedirectUrl = url('/vanilla/settings/managecategories'); } } else { throw forbiddenException('GET'); } return $this->render('Blank', 'Utility', 'Dashboard'); }
/** * Determine whether user can register with this username. * * @since 2.0.0 * @access public * @param string $Name Username to be checked. */ public function usernameAvailable($Name = '') { $this->_DeliveryType = DELIVERY_TYPE_BOOL; $Available = true; if (c('Garden.Registration.NameUnique', true) && $Name != '') { $UserModel = Gdn::userModel(); if ($UserModel->getByUsername($Name)) { $Available = false; } } if (!$Available) { $this->Form->addError(sprintf(t('%s unavailable'), t('Name'))); } $this->render(); }
/** * Determine whether user can register with this username. * * @since 2.0.0 * @access public * @param string $Name Username to be checked. */ public function UsernameAvailable($Name = '') { $this->_DeliveryType = DELIVERY_TYPE_BOOL; $Available = TRUE; if (C('Garden.Registration.NameUnique', TRUE) && $Name != '') { $UserModel = Gdn::UserModel(); if ($UserModel->GetByUsername($Name)) { $Available = FALSE; } } if (!$Available) { $this->Form->AddError(sprintf(T('%s unavailable'), T('Name'))); } $this->Render(); }
/** * Set where to go after signin. * * @access public * @since 2.0.0 * * @param string $Target Where we're requested to go to. * @return string URL to actually go to (validated & safe). */ public function Target($Target = FALSE) { if ($Target === FALSE) { $Target = $this->Form->GetFormValue('Target', FALSE); if (!$Target) { $Target = $this->Request->Get('Target', '/'); } } // Make sure that the target is a valid url. if (!preg_match('`(^https?://)`', $Target)) { $Target = '/' . ltrim($Target, '/'); // Never redirect back to signin. if (preg_match('`^/entry/signin`i', $Target)) { $Target = '/'; } } else { $MyHostname = parse_url(Gdn::Request()->Domain(), PHP_URL_HOST); $TargetHostname = parse_url($Target, PHP_URL_HOST); // Only allow external redirects to trusted domains. $TrustedDomains = C('Garden.TrustedDomains', TRUE); if (is_array($TrustedDomains)) { // Add this domain to the trusted hosts. $TrustedDomains[] = $MyHostname; $this->EventArguments['TrustedDomains'] =& $TrustedDomains; $this->FireEvent('BeforeTargetReturn'); } if ($TrustedDomains === TRUE) { return $Target; } elseif (count($TrustedDomains) == 0) { // Only allow http redirects if they are to the same host name. if ($MyHostname != $TargetHostname) { $Target = ''; } } else { // Loop the trusted domains looking for a match $Match = FALSE; foreach ($TrustedDomains as $TrustedDomain) { if (StringEndsWith($TargetHostname, $TrustedDomain, TRUE)) { $Match = TRUE; } } if (!$Match) { $Target = ''; } } } return $Target; }
/** * Set where to go after signin. * * @access public * @since 2.0.0 * * @param string $Target Where we're requested to go to. * @return string URL to actually go to (validated & safe). */ public function target($Target = false) { if ($Target === false) { $Target = $this->Form->getFormValue('Target', false); if (!$Target) { $Target = $this->Request->get('Target', $this->Request->get('target', '/')); } } // Make sure that the target is a valid url. if (!preg_match('`(^https?://)`', $Target)) { $Target = '/' . ltrim($Target, '/'); // Never redirect back to signin. if (preg_match('`^/entry/signin`i', $Target)) { $Target = '/'; } } return $Target; }
/** * Allows users to bookmark conversations. * * @param int $ConversationID Unique ID of conversation to view. * @param string $TransientKey Single-use hash to prove intent. */ public function bookmark($ConversationID = '', $TransientKey = '') { $Session = Gdn::session(); $Bookmark = null; // Validate & do bookmarking. if (is_numeric($ConversationID) && $ConversationID > 0 && $Session->UserID > 0 && $Session->validateTransientKey($TransientKey)) { $Bookmark = $this->ConversationModel->bookmark($ConversationID, $Session->UserID); } // Report success or error if ($Bookmark === false) { $this->Form->addError('ErrorBool'); } else { $this->setJson('Bookmark', $Bookmark); } // Redirect back where the user came from if necessary if ($this->_DeliveryType == DELIVERY_TYPE_ALL) { redirect($_SERVER['HTTP_REFERER']); } else { $this->render(); } }
/** * Revoke an invitation. * * @since 2.0.0 * @param int $InvitationID Unique identifier. * @throws Exception Throws an exception when the invitation isn't found or the user doesn't have permission to delete it. */ public function uninvite($InvitationID) { $this->permission('Garden.SignIn.Allow'); if (!$this->Form->authenticatedPostBack()) { throw forbiddenException('GET'); } $InvitationModel = new InvitationModel(); $Session = Gdn::session(); try { $Valid = $InvitationModel->delete($InvitationID, $this->UserModel); if ($Valid) { $this->informMessage(t('The invitation was removed successfully.')); $this->jsonTarget(".js-invitation[data-id=\"{$InvitationID}\"]", '', 'SlideUp'); } } catch (Exception $ex) { $this->Form->addError(strip_tags($ex->getMessage())); } if ($this->Form->errorCount() == 0) { $this->render('Blank', 'Utility'); } }
/** * Set the icon for an addon. * * @param int $AddonID Specified addon id. * @throws Exception Addon not found. */ public function icon($AddonID = '') { $Session = Gdn::session(); if (!$Session->isValid()) { $this->Form->addError('You must be authenticated in order to use this form.'); } $Addon = $this->AddonModel->getID($AddonID); if (!$Addon) { throw notFoundException('Addon'); } if ($Session->UserID != $Addon['InsertUserID']) { $this->permission('Addons.Addon.Manage'); } $this->addModule('AddonHelpModule', 'Panel'); $this->Form->setModel($this->AddonModel); $this->Form->addHidden('AddonID', $AddonID); if ($this->Form->authenticatedPostBack()) { $UploadImage = new Gdn_UploadImage(); try { // Validate the upload $imageLocation = $UploadImage->validateUpload('Icon'); $TargetImage = $this->saveIcon($imageLocation); } catch (Exception $ex) { $this->Form->addError($ex); } // If there were no errors, remove the old picture and insert the picture if ($this->Form->errorCount() == 0) { if ($Addon['Icon']) { $UploadImage->delete($Addon['Icon']); } $this->AddonModel->save(array('AddonID' => $AddonID, 'Icon' => $TargetImage)); } // If there were no problems, redirect back to the addon if ($this->Form->errorCount() == 0) { $this->RedirectUrl = Url('/addon/' . AddonModel::slug($Addon)); } } $this->render(); }
/** * Set where to go after signin. * * @access public * @since 2.0.0 * * @param string $Target Where we're requested to go to. * @return string URL to actually go to (validated & safe). */ public function Target($Target = FALSE) { if ($Target === FALSE) { $Target = $this->Form->GetFormValue('Target', FALSE); if (!$Target) $Target = $this->Request->Get('Target', '/'); } // Make sure that the target is a valid url. if (!preg_match('`(^https?://)`', $Target)) { $Target = '/'.ltrim($Target, '/'); } else { $MyHostname = parse_url(Gdn::Request()->Domain(),PHP_URL_HOST); $TargetHostname = parse_url($Target, PHP_URL_HOST); // Dont allow external redirects, but fire an event to allow override $AllowExternalRedirect = C('Garden.Target.AllowExternalRedirect', FALSE); $Sender->EventArguments['AllowExternalRedirect'] = &$AllowExternalRedirect; $this->FireEvent('BeforeTargetReturn'); if (!$AllowExternalRedirect && $MyHostname != $TargetHostname) return ''; } return $Target; }
/** * Attach editor anywhere 'BodyBox' is used. * * It is not being used for editing a posted reply, so find another event to hook into. * * @param Gdn_Form $Sender */ public function gdn_form_beforeBodyBox_handler($Sender, $Args) { // TODO have some way to prevent this content from getting loaded when in embedded. // The only problem is figuring out how to know when content is embedded. $attributes = array(); if (val('Attributes', $Args)) { $attributes = val('Attributes', $Args); } // TODO move this property to constructor $this->Format = $Sender->getValue('Format'); // Make sure we have some sort of format. if (!$this->Format) { $this->Format = c('Garden.InputFormatter', 'Html'); $Sender->setValue('Format', $this->Format); } // If force Wysiwyg enabled in settings $needsConversion = !in_array($this->Format, array('Html', 'Wysiwyg')); if (c('Garden.InputFormatter', 'Wysiwyg') == 'Wysiwyg' && $this->ForceWysiwyg == true && $needsConversion) { $wysiwygBody = Gdn_Format::to($Sender->getValue('Body'), $this->Format); $Sender->setValue('Body', $wysiwygBody); $this->Format = 'Wysiwyg'; $Sender->setValue('Format', $this->Format); } if (in_array(strtolower($this->Format), array_map('strtolower', $this->Formats))) { $c = Gdn::controller(); // Set minor data for view $c->setData('_EditorInputFormat', $this->Format); // Get the generated editor toolbar from getEditorToolbar, and assign it data object for view. if (!isset($c->Data['_EditorToolbar'])) { $editorToolbar = $this->getEditorToolbar($attributes); $this->EventArguments['EditorToolbar'] =& $editorToolbar; $this->fireEvent('InitEditorToolbar'); // Set data for view $c->setData('_EditorToolbar', $editorToolbar); } $c->addDefinition('canUpload', $this->canUpload); $c->setData('_canUpload', $this->canUpload); // Determine which controller (post or discussion) is invoking this. // At the moment they're both the same, but in future you may want // to know this information to modify it accordingly. $View = $c->fetchView('editor', '', 'plugins/editor'); $Args['BodyBox'] .= $View; } }
/** * Allows user to bookmark or unbookmark a discussion. * * If the discussion isn't bookmarked by the user, this bookmarks it. * If it is already bookmarked, this unbookmarks it. * * @since 2.0.0 * @access public * * @param int $DiscussionID Unique discussion ID. */ public function bookmark($DiscussionID = null) { // Make sure we are posting back. if (!$this->Request->isAuthenticatedPostBack()) { throw permissionException('Javascript'); } $Session = Gdn::session(); if (!$Session->UserID) { throw permissionException('SignedIn'); } // Check the form to see if the data was posted. $Form = new Gdn_Form(); $DiscussionID = $Form->getFormValue('DiscussionID', $DiscussionID); $Bookmark = $Form->getFormValue('Bookmark', null); $UserID = $Form->getFormValue('UserID', $Session->UserID); // Check the permission on the user. if ($UserID != $Session->UserID) { $this->permission('Garden.Moderation.Manage'); } $Discussion = $this->DiscussionModel->getID($DiscussionID); if (!$Discussion) { throw notFoundException('Discussion'); } $Bookmark = $this->DiscussionModel->bookmark($DiscussionID, $UserID, $Bookmark); // Set the new value for api calls and json targets. $this->setData(array('UserID' => $UserID, 'DiscussionID' => $DiscussionID, 'Bookmarked' => (bool) $Bookmark)); setValue('Bookmarked', $Discussion, (int) $Bookmark); // Update the user's bookmark count $CountBookmarks = $this->DiscussionModel->setUserBookmarkCount($UserID); $this->jsonTarget('.User-CountBookmarks', (string) $CountBookmarks); // Short circuit if this is an api call. if ($this->deliveryType() === DELIVERY_TYPE_DATA) { $this->render('Blank', 'Utility', 'Dashboard'); return; } // Return the appropriate bookmark. require_once $this->fetchViewLocation('helper_functions', 'Discussions'); $Html = bookmarkButton($Discussion); // $this->jsonTarget(".Section-DiscussionList #Discussion_$DiscussionID .Bookmark,.Section-Discussion .PageTitle .Bookmark", $Html, 'ReplaceWith'); $this->jsonTarget("!element", $Html, 'ReplaceWith'); // Add the bookmark to the bookmarks module. if ($Bookmark) { // Grab the individual bookmark and send it to the client. $Bookmarks = new BookmarkedModule($this); if ($CountBookmarks == 1) { // When there is only one bookmark we have to get the whole module. $Target = '#Panel'; $Type = 'Append'; $Bookmarks->getData(); $Data = $Bookmarks->toString(); } else { $Target = '#Bookmark_List'; $Type = 'Prepend'; $Loc = $Bookmarks->fetchViewLocation('discussion'); ob_start(); include $Loc; $Data = ob_get_clean(); } $this->jsonTarget($Target, $Data, $Type); } else { // Send command to remove bookmark html. if ($CountBookmarks == 0) { $this->jsonTarget('#Bookmarks', null, 'Remove'); } else { $this->jsonTarget('#Bookmark_' . $DiscussionID, null, 'Remove'); } } $this->render('Blank', 'Utility', 'Dashboard'); }
/** * Check minimum requirements for Garden. * * @since 2.0.0 * @access private * @return bool Whether platform passes requirement check. */ private function _checkPrerequisites() { // Make sure we are running at least PHP 5.1 if (version_compare(phpversion(), ENVIRONMENT_PHP_VERSION) < 0) { $this->Form->addError(sprintf(t('You are running PHP version %1$s. Vanilla requires PHP %2$s or greater. You must upgrade PHP before you can continue.'), phpversion(), ENVIRONMENT_PHP_VERSION)); } // Make sure PDO is available if (!class_exists('PDO')) { $this->Form->addError(t('You must have the PDO module enabled in PHP in order for Vanilla to connect to your database.')); } if (!defined('PDO::MYSQL_ATTR_USE_BUFFERED_QUERY')) { $this->Form->addError(t('You must have the MySQL driver for PDO enabled in order for Vanilla to connect to your database.')); } // Make sure that the correct filesystem permissions are in place. $PermissionProblem = false; // Make sure the appropriate folders are writable. $ProblemDirectories = array(); if (!is_readable(PATH_CONF) || !isWritable(PATH_CONF)) { $ProblemDirectories[] = PATH_CONF; } if (!is_readable(PATH_UPLOADS) || !isWritable(PATH_UPLOADS)) { $ProblemDirectories[] = PATH_UPLOADS; } if (!is_readable(PATH_CACHE) || !isWritable(PATH_CACHE)) { $ProblemDirectories[] = PATH_CACHE; } if (file_exists(PATH_CACHE . '/Smarty/compile') && (!is_readable(PATH_CACHE . '/Smarty/compile') || !isWritable(PATH_CACHE . '/Smarty/compile'))) { $ProblemDirectories[] = PATH_CACHE . '/Smarty/compile'; } // Display our permission errors. if (count($ProblemDirectories) > 0) { $PermissionProblem = true; $PermissionError = t('Some folders don\'t have correct permissions.', '<p>These folders must be readable and writable by the web server:</p>'); $PermissionHelp = '<pre>' . implode("\n", $ProblemDirectories) . '</pre>'; $this->Form->addError($PermissionError . $PermissionHelp); } // Make sure the config folder is writable. if (!$PermissionProblem) { $ConfigFile = Gdn::config()->defaultPath(); if (file_exists($ConfigFile)) { // Make sure the config file is writable. if (!is_readable($ConfigFile) || !isWritable($ConfigFile)) { $this->Form->addError(sprintf(t('Your configuration file does not have the correct permissions. PHP needs to be able to read and write to this file: <code>%s</code>'), $ConfigFile)); $PermissionProblem = true; } } else { // Make sure the config file can be created. if (!is_writeable(dirname($ConfigFile))) { $this->Form->addError(sprintf(t('Your configuration file cannot be created. PHP needs to be able to create this file: <code>%s</code>'), $ConfigFile)); $PermissionProblem = true; } } } // Make sure the cache folder is writable if (!$PermissionProblem) { if (!file_exists(PATH_CACHE . '/Smarty')) { mkdir(PATH_CACHE . '/Smarty'); } if (!file_exists(PATH_CACHE . '/Smarty/cache')) { mkdir(PATH_CACHE . '/Smarty/cache'); } if (!file_exists(PATH_CACHE . '/Smarty/compile')) { mkdir(PATH_CACHE . '/Smarty/compile'); } } return $this->Form->errorCount() == 0 ? true : false; }