Helps with the rendering of form controls that link directly to a data model.
Since: 2.0
Author: Mark O'Sullivan (markm@vanillaforums.com)
Inheritance: extends Gdn_Pluggable
コード例 #1
0
 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();
 }
コード例 #2
0
 /**
  *
  * @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;
 }
コード例 #3
0
 /**
  * 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();
 }
コード例 #4
0
	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();
	}
コード例 #5
0
 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');
 }
コード例 #6
0
 /**
  * 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();
 }
コード例 #7
0
 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');
 }
コード例 #8
0
 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');
     }
 }
コード例 #9
0
ファイル: default.php プロジェクト: 3marproof/vanilla
 /**
  *
  * @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');
 }
コード例 #10
0
 /**
  * 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();
 }
コード例 #11
0
 /**
  * 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);
 }
コード例 #12
0
 /**
  * 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();
 }
コード例 #13
0
ファイル: condition.php プロジェクト: caidongyun/vanilla
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>';
}
コード例 #14
0
 /** 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;
 }
コード例 #15
0
 /**
  * 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;
 }
コード例 #16
0
 /**
  * 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();
 }
コード例 #17
0
 /**
  * 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();
 }
コード例 #18
0
 /**
  * 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();
 }
コード例 #19
0
 /**
  * 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');
 }
コード例 #20
0
 /**
  * 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();
 }
コード例 #21
0
 /**
  * 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();
 }
コード例 #22
0
 /**
  * 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;
 }
コード例 #23
0
 /**
  * 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;
 }
コード例 #24
0
 /**
  * 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();
     }
 }
コード例 #25
0
 /**
  * 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');
     }
 }
コード例 #26
0
 /**
  * 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();
 }
コード例 #27
0
 /**
  * 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;
 }
コード例 #28
0
 /**
  * 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;
     }
 }
コード例 #29
0
 /**
  * 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');
 }
コード例 #30
0
 /**
  * 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;
 }