/** * Emulate a call to index.php?p=$vanilla_module_path * Much of this ripped out of Vanilla's index.php */ public function view($segments) { // if a static asset, return it outright $asset = $this->is_static_asset($segments); if ($asset) { return \Response::make(\File::get($asset))->header('Content-Type', $this->get_content_type($asset)); } // otherwise, dispatch into vanilla $user = $this->user; $bootstrap = new VanillaBootstrap(); $bootstrap->call(function () use($user, $segments) { // Create the session and stuff the user in \Gdn::Authenticator()->SetIdentity($user->getKey(), false); \Gdn::Session()->Start(false, false); \Gdn::Session()->SetPreference('Authenticator', 'Gdn_Authenticator'); // Create and configure the dispatcher. $Dispatcher = \Gdn::Dispatcher(); $EnabledApplications = \Gdn::ApplicationManager()->EnabledApplicationFolders(); $Dispatcher->EnabledApplicationFolders($EnabledApplications); $Dispatcher->PassProperty('EnabledApplications', $EnabledApplications); // Process the request. $Dispatcher->Start(); $Dispatcher->Dispatch(implode('/', $segments)); }); }
/** * Use 404 handler to look for a SimplePage. */ public function gdn_dispatcher_notFound_handler($dispatcher, $args) { $requestUri = Gdn::Request()->Path(); $discussionModel = new DiscussionModel(); $result = $discussionModel->GetWhere(array('Type' => 'SimplePage', 'ForeignID' => $requestUri))->FirstRow(DATASET_TYPE_ARRAY); // Page exists with requested slug, so dispatch; no redirect. if ($discussionID = val('DiscussionID', $result)) { SaveToConfig('SimplePage.Found', true, false); Gdn::Dispatcher()->Dispatch('/discussion/' . $discussionID); exit; } }
public function Slice($SliceName, $Arguments = array()) { $CurrentPath = Gdn::Request()->Path(); $ExplodedPath = explode('/', $CurrentPath); switch ($this instanceof Gdn_IPlugin) { case TRUE: $ReplacementIndex = 2; break; case FALSE: $ReplacementIndex = 1; break; } if ($ExplodedPath[0] == strtolower(Gdn::Dispatcher()->Application()) && $ExplodedPath[1] == strtolower(Gdn::Dispatcher()->Controller())) { $ReplacementIndex++; } $ExplodedPath[$ReplacementIndex] = $SliceName; $SlicePath = implode('/', $ExplodedPath); return Gdn::Slice($SlicePath); }
public function API($Path, $Post = FALSE) { // Build the url. $Url = 'https://graph.facebook.com/' . ltrim($Path, '/'); $AccessToken = $this->AccessToken(); if (!$AccessToken) { throw new Gdn_UserException("You don't have a valid Facebook connection."); } if (strpos($Url, '?') === false) { $Url .= '?'; } else { $Url .= '&'; } $Url .= 'access_token=' . urlencode($AccessToken); $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_URL, $Url); if ($Post !== false) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $Post); Trace(" POST {$Url}"); } else { Trace(" GET {$Url}"); } $Response = curl_exec($ch); $HttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $ContentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch); Gdn::Controller()->SetJson('Type', $ContentType); if (strpos($ContentType, 'javascript') !== FALSE) { $Result = json_decode($Response, TRUE); if (isset($Result['error'])) { Gdn::Dispatcher()->PassData('FacebookResponse', $Result); throw new Gdn_UserException($Result['error']['message']); } } else { $Result = $Response; } return $Result; }
public static function Pagename() { $Application = Gdn::Dispatcher()->Application(); $Controller = Gdn::Dispatcher()->Controller(); switch ($Controller) { case 'discussions': case 'discussion': case 'post': return 'discussions'; case 'inbox': return 'inbox'; case 'activity': return 'activity'; case 'profile': $Args = Gdn::Dispatcher()->ControllerArguments(); if (!sizeof($Args) || sizeof($Args) && $Args[0] == Gdn::Authenticator()->GetIdentity()) { return 'profile'; } break; } return 'unknown'; }
/** * Application Gateway * * @author Mark O'Sullivan <*****@*****.**> * @author Todd Burry <*****@*****.**> * @author Tim Gunter <*****@*****.**> * @copyright 2003 Vanilla Forums, Inc * @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2 * @package Garden * @since 2.0 */ define('APPLICATION', 'Vanilla'); define('APPLICATION_VERSION', '2.2.16.1'); // Report and track all errors. error_reporting(E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR); ini_set('display_errors', 0); ini_set('track_errors', 1); ob_start(); // Define the constants we need to get going. define('DS', '/'); define('PATH_ROOT', getcwd()); // Include the bootstrap to configure the framework. require_once PATH_ROOT . '/bootstrap.php'; // Create and configure the dispatcher. $Dispatcher = Gdn::Dispatcher(); $EnabledApplications = Gdn::ApplicationManager()->EnabledApplicationFolders(); $Dispatcher->EnabledApplicationFolders($EnabledApplications); $Dispatcher->PassProperty('EnabledApplications', $EnabledApplications); // Process the request. $Dispatcher->Start(); $Dispatcher->Dispatch();
/** * Render an exception as the sole output. * * @param Exception $Ex The exception to render. */ public function RenderException($Ex) { if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) { try { if (is_a($Ex, 'Gdn_UserException')) { Gdn::Dispatcher()->PassData('Code', $Ex->getCode())->PassData('Exception', $Ex->getMessage())->PassData('Message', $Ex->getMessage())->PassData('Trace', $Ex->getTraceAsString())->PassData('Url', Url())->PassData('Breadcrumbs', $this->Data('Breadcrumbs', array()))->Dispatch('/home/error'); } else { switch ($Ex->getCode()) { case 401: Gdn::Dispatcher()->PassData('Message', $Ex->getMessage())->PassData('Url', Url())->Dispatch('DefaultPermission'); break; case 404: Gdn::Dispatcher()->PassData('Message', $Ex->getMessage())->PassData('Url', Url())->Dispatch('Default404'); break; default: Gdn_ExceptionHandler($Ex); } } } catch (Exception $Ex2) { Gdn_ExceptionHandler($Ex); } return; } // Make sure the database connection is closed before exiting. $this->Finalize(); $this->SendHeaders(); $Code = $Ex->getCode(); $Data = array('Code' => $Code, 'Exception' => $Ex->getMessage(), 'Class' => get_class($Ex)); if (Debug()) { if ($Trace = Trace()) { // Clear passwords from the trace. array_walk_recursive($Trace, function (&$Value, $Key) { if (in_array(strtolower($Key), array('password'))) { $Value = '***'; } }); $Data['Trace'] = $Trace; } if (!is_a($Ex, 'Gdn_UserException')) { $Data['StackTrace'] = $Ex->getTraceAsString(); } $Data['Data'] = $this->Data; } // Try cleaning out any notices or errors. @ob_clean(); if ($Code >= 400 && $Code <= 505) { safeHeader("HTTP/1.0 {$Code}", TRUE, $Code); } else { safeHeader('HTTP/1.0 500', TRUE, 500); } switch ($this->DeliveryMethod()) { case DELIVERY_METHOD_JSON: if (($Callback = $this->Request->GetValueFrom(Gdn_Request::INPUT_GET, 'callback', FALSE)) && $this->AllowJSONP()) { safeHeader('Content-Type: application/javascript', TRUE); // This is a jsonp request. exit($Callback . '(' . json_encode($Data) . ');'); } else { safeHeader('Content-Type: application/json', TRUE); // This is a regular json request. exit(json_encode($Data)); } break; // case DELIVERY_METHOD_XHTML: // Gdn_ExceptionHandler($Ex); // break; // case DELIVERY_METHOD_XHTML: // Gdn_ExceptionHandler($Ex); // break; case DELIVERY_METHOD_XML: safeHeader('Content-Type: text/xml', TRUE); array_map('htmlspecialchars', $Data); exit("<Exception><Code>{$Data['Code']}</Code><Class>{$Data['Class']}</Class><Message>{$Data['Exception']}</Message></Exception>"); break; default: safeHeader('Content-Type: text/plain', TRUE); exit($Ex->getMessage()); } }
/** * Set new password for current user. * * @since 2.0.0 * @access public */ public function Password() { $this->Permission('Garden.SignIn.Allow'); // Don't allow password editing if using SSO Connect ONLY. // This is for security. We encountered the case where a customer charges // for membership using their external application and use SSO to let // their customers into Vanilla. If you allow those people to change their // password in Vanilla, they will then be able to log into Vanilla using // Vanilla's login form regardless of the state of their membership in the // external app. if (C('Garden.Registration.Method') == 'Connect') { Gdn::Dispatcher()->Dispatch('DefaultPermission'); exit; } Gdn::UserModel()->AddPasswordStrength($this); // Get user data and set up form $this->GetUserInfo(); $this->Form->SetModel($this->UserModel); $this->AddDefinition('Username', $this->User->Name); if ($this->Form->AuthenticatedPostBack() === TRUE) { $this->Form->SetFormValue('UserID', $this->User->UserID); $this->UserModel->DefineSchema(); // $this->UserModel->Validation->AddValidationField('OldPassword', $this->Form->FormValues()); // No password may have been set if they have only signed in with a connect plugin if (!$this->User->HashMethod || $this->User->HashMethod == "Vanilla") { $this->UserModel->Validation->ApplyRule('OldPassword', 'Required'); $this->UserModel->Validation->ApplyRule('OldPassword', 'OldPassword', 'Your old password was incorrect.'); } $this->UserModel->Validation->ApplyRule('Password', 'Required'); $this->UserModel->Validation->ApplyRule('Password', 'Strength'); $this->UserModel->Validation->ApplyRule('Password', 'Match'); if ($this->Form->Save()) { $this->InformMessage(Sprite('Check', 'InformSprite') . T('Your password has been changed.'), 'Dismissable AutoDismiss HasSprite'); $this->Form->ClearInputs(); } } $this->Title(T('Change My Password')); $this->_SetBreadcrumbs(T('Change My Password'), '/profile/password'); $this->Render(); }
/** * Do permission check. * * @since 2.0.0 * @access protected */ protected function _Permission() { $this->Permission('Garden.Roles.Manage'); if (!C('Garden.Roles.Manage', TRUE)) { Gdn::Dispatcher()->Dispatch('DefaultPermission'); return FALSE; } return TRUE; }
public function Handshake($AuthenticationSchemeAlias = 'default') { try { // Don't show anything if handshaking not turned on by an authenticator if (!Gdn::Authenticator()->CanHandshake()) { throw new Exception(); } // Try to load the authenticator $Authenticator = Gdn::Authenticator()->AuthenticateWith($AuthenticationSchemeAlias); // Try to grab the authenticator data $Payload = $Authenticator->GetHandshake(); if ($Payload === FALSE) { Gdn::Request()->WithURI('dashboard/entry/auth/password'); return Gdn::Dispatcher()->Dispatch(); } } catch (Exception $e) { Gdn::Request()->WithURI('/entry/signin'); return Gdn::Dispatcher()->Dispatch(); } $this->AddJsFile('entry.js'); $this->View = 'handshake'; $this->HandshakeScheme = $AuthenticationSchemeAlias; $this->Form->SetModel($this->UserModel); $this->Form->AddHidden('ClientHour', date('G', time())); // Use the server's current hour as a default $Target = GetIncomingValue('Target', '/'); $this->Form->AddHidden('Target', GetIncomingValue('Target', '/')); $UserKey = $Authenticator->GetUserKeyFromHandshake($Payload); $ConsumerKey = $Authenticator->GetProviderKeyFromHandshake($Payload); $TokenKey = $Authenticator->GetTokenKeyFromHandshake($Payload); $UserName = $Authenticator->GetUserNameFromHandshake($Payload); $UserEmail = $Authenticator->GetUserEmailFromHandshake($Payload); $PreservedKeys = array('UserKey', 'Token', 'Consumer', 'Email', 'Name', 'Gender', 'HourOffset'); $UserID = 0; // Manual user sync is disabled. No hand holding will occur for users. if (!C('Garden.Authenticator.SyncScreen', TRUE)) { $UserID = $this->UserModel->Synchronize($UserKey, array('Name' => $UserName, 'Email' => $UserEmail)); if ($UserID > 0) { // Account created successfully. // Finalize the link between the forum user and the foreign userkey $Authenticator->Finalize($UserKey, $UserID, $ConsumerKey, $TokenKey, $Payload); /// ... and redirect them appropriately $Route = $this->RedirectTo(); if ($Route !== FALSE) { Redirect($Route); } else { Redirect('/'); } } else { // Account not created. $Authenticator->DeleteCookie(); Gdn::Request()->WithRoute('DefaultController'); return Gdn::Dispatcher()->Dispatch(); } } else { if ($this->Form->IsPostBack() === TRUE) { $FormValues = $this->Form->FormValues(); if (ArrayValue('StopLinking', $FormValues)) { $Authenticator->DeleteCookie(); Gdn::Request()->WithRoute('DefaultController'); return Gdn::Dispatcher()->Dispatch(); } elseif (ArrayValue('NewAccount', $FormValues)) { // Try and synchronize the user with the new username/email. $FormValues['Name'] = $FormValues['NewName']; $FormValues['Email'] = $FormValues['NewEmail']; $UserID = $this->UserModel->Synchronize($UserKey, $FormValues); $this->Form->SetValidationResults($this->UserModel->ValidationResults()); } else { // Try and sign the user in. $PasswordAuthenticator = Gdn::Authenticator()->AuthenticateWith('password'); $PasswordAuthenticator->HookDataField('Email', 'SignInEmail'); $PasswordAuthenticator->HookDataField('Password', 'SignInPassword'); $PasswordAuthenticator->FetchData($this->Form); $UserID = $PasswordAuthenticator->Authenticate(); if ($UserID < 0) { $this->Form->AddError('ErrorPermission'); } else { if ($UserID == 0) { $this->Form->AddError('ErrorCredentials'); } } if ($UserID > 0) { $Data = $FormValues; $Data['UserID'] = $UserID; $Data['Email'] = ArrayValue('SignInEmail', $FormValues, ''); $UserID = $this->UserModel->Synchronize($UserKey, $Data); } } if ($UserID > 0) { // The user has been created successfully, so sign in now // Finalize the link between the forum user and the foreign userkey $Authenticator->Finalize($UserKey, $UserID, $ConsumerKey, $TokenKey, $Payload); /// ... and redirect them appropriately $Route = $this->RedirectTo(); if ($Route !== FALSE) { Redirect($Route); } } else { // Add the hidden inputs back into the form. foreach ($FormValues as $Key => $Value) { if (in_array($Key, $PreservedKeys)) { $this->Form->AddHidden($Key, $Value); } } } } else { $Id = Gdn::Authenticator()->GetIdentity(TRUE); if ($Id > 0) { // The user is signed in so we can just go back to the homepage. Redirect($Target); } $Name = $UserName; $Email = $UserEmail; // Set the defaults for a new user. $this->Form->SetFormValue('NewName', $Name); $this->Form->SetFormValue('NewEmail', $Email); // Set the default for the login. $this->Form->SetFormValue('SignInEmail', $Email); $this->Form->SetFormValue('Handshake', 'NEW'); // Add the handshake data as hidden fields. $this->Form->AddHidden('Name', $Name); $this->Form->AddHidden('Email', $Email); $this->Form->AddHidden('UserKey', $UserKey); $this->Form->AddHidden('Token', $TokenKey); $this->Form->AddHidden('Consumer', $ConsumerKey); } $this->SetData('Name', ArrayValue('Name', $this->Form->HiddenInputs)); $this->SetData('Email', ArrayValue('Email', $this->Form->HiddenInputs)); $this->Render(); } }
/** * Default profile page. * * If current user's profile, get notifications. Otherwise show their activity (if available) or discussions. * * @since 2.0.0 * @access public * @param mixed $UserReference Unique identifier, possible ID or username. * @param string $Username. * @param int $UserID Unique ID. */ public function Index($UserReference = '', $Username = '', $UserID = '') { $this->GetUserInfo($UserReference, $Username, $UserID); if ($this->User->Admin == 2 && $this->Head) { // Don't index internal accounts. This is in part to prevent vendors from getting endless Google alerts. $this->Head->AddTag('meta', array('name' => 'robots', 'content' => 'noindex')); $this->Head->AddTag('meta', array('name' => 'googlebot', 'content' => 'noindex')); } if ($this->User->UserID == Gdn::Session()->UserID) { return $this->Notifications(); } elseif (C('Garden.Profile.ShowActivities', TRUE)) { return $this->Activity($UserReference, $Username, $UserID); } else { return Gdn::Dispatcher()->Dispatch('/profile/discussions/' . ConcatSep('/', rawurlencode($UserReference), rawurlencode($Username), rawurlencode($UserID))); } }
public function Index($DiscussionID = '', $DiscussionStub = '', $Offset = '', $Limit = '') { $this->AddCssFile('vanilla.css'); $Session = Gdn::Session(); $this->AddJsFile('jquery.resizable.js'); $this->AddJsFile('jquery.ui.packed.js'); $this->AddJsFile('jquery.autogrow.js'); // $this->AddJsFile('jquery.gardenmorepager.js'); $this->AddJsFile('options.js'); $this->AddJsFile('bookmark.js'); $this->AddJsFile('discussion.js'); $this->AddJsFile('autosave.js'); // Load the discussion record $DiscussionID = is_numeric($DiscussionID) && $DiscussionID > 0 ? $DiscussionID : 0; $this->SetData('Discussion', $this->DiscussionModel->GetID($DiscussionID), TRUE); if (!is_object($this->Discussion)) { return Gdn::Dispatcher()->Dispatch('Default404'); } // Check Permissions $this->Permission('Vanilla.Discussions.View', TRUE, 'Category', $this->Discussion->CategoryID); $this->SetData('CategoryID', $this->CategoryID = $this->Discussion->CategoryID, TRUE); // Setup $this->Title($this->Discussion->Name); // Actual number of comments, excluding the discussion itself $ActualResponses = $this->Discussion->CountComments - 1; // Define the query offset & limit if (!is_numeric($Limit) || $Limit < 0) { $Limit = C('Vanilla.Comments.PerPage', 50); } $OffsetProvided = $Offset != ''; list($Offset, $Limit) = OffsetLimit($Offset, $Limit); // If $Offset isn't defined, assume that the user has not clicked to // view a next or previous page, and this is a "view" to be counted. if ($Offset == '') { $this->DiscussionModel->AddView($DiscussionID); } $this->Offset = $Offset; if (C('Vanilla.Comments.AutoOffset')) { if (!is_numeric($this->Offset) || $this->Offset < 0 || !$OffsetProvided) { // Round down to the appropriate offset based on the user's read comments & comments per page $CountCommentWatch = $this->Discussion->CountCommentWatch > 0 ? $this->Discussion->CountCommentWatch : 0; if ($CountCommentWatch > $ActualResponses) { $CountCommentWatch = $ActualResponses; } // (((67 comments / 10 perpage) = 6.7) rounded down = 6) * 10 perpage = offset 60; $this->Offset = floor($CountCommentWatch / $Limit) * $Limit; } if ($ActualResponses <= $Limit) { $this->Offset = 0; } if ($this->Offset == $ActualResponses) { $this->Offset -= $Limit; } } else { if ($this->Offset == '') { $this->Offset = 0; } } if ($this->Offset < 0) { $this->Offset = 0; } // Set the canonical url to have the proper page title. $this->CanonicalUrl(Url(ConcatSep('/', 'discussion/' . $this->Discussion->DiscussionID . '/' . Gdn_Format::Url($this->Discussion->Name), PageNumber($this->Offset, $Limit, TRUE)), TRUE)); // Make sure to set the user's discussion watch records $this->CommentModel->SetWatch($this->Discussion, $Limit, $this->Offset, $this->Discussion->CountComments); // Load the comments $this->SetData('CommentData', $this->CommentModel->Get($DiscussionID, $Limit, $this->Offset), TRUE); $this->SetData('Comments', $this->CommentData); // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->Pager = $PagerFactory->GetPager('Pager', $this); $this->Pager->ClientID = 'Pager'; $this->Pager->Configure($this->Offset, $Limit, $ActualResponses, 'discussion/' . $DiscussionID . '/' . Gdn_Format::Url($this->Discussion->Name) . '/%1$s'); // $this->Pager->MoreCode = '%1$s more comments'; // $this->Pager->LessCode = '%1$s older comments'; // $this->Pager->ClientID = 'Pager'; // $this->Pager->Configure( // $this->Offset, // $Limit, // $ActualResponses, // 'discussion/'.$DiscussionID.'/'.Gdn_Format::Url($this->Discussion->Name).'/%1$s/%2$s/' // ); // Define the form for the comment input $this->Form = Gdn::Factory('Form', 'Comment'); $this->Form->Action = Url('/vanilla/post/comment/'); $this->DiscussionID = $this->Discussion->DiscussionID; $this->Form->AddHidden('DiscussionID', $this->DiscussionID); $this->Form->AddHidden('CommentID', ''); // Retrieve & apply the draft if there is one: $DraftModel = new DraftModel(); $Draft = $DraftModel->Get($Session->UserID, 0, 1, $this->Discussion->DiscussionID)->FirstRow(); $this->Form->AddHidden('DraftID', $Draft ? $Draft->DraftID : ''); if ($Draft) { $this->Form->SetFormValue('Body', $Draft->Body); } // Deliver json data if necessary if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->SetJson('LessRow', $this->Pager->ToString('less')); $this->SetJson('MoreRow', $this->Pager->ToString('more')); $this->View = 'comments'; } // Add Modules $this->AddModule('NewDiscussionModule'); $this->AddModule('CategoriesModule'); $BookmarkedModule = new BookmarkedModule($this); $BookmarkedModule->GetData(); $this->AddModule($BookmarkedModule); $this->FireEvent('BeforeDiscussionRender'); $this->Render(); }
<?php // User. Gdn::FactoryInstall(Gdn::AliasUserModel, 'Gdn_UserModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.usermodel.php', Gdn::FactorySingleton); // Permissions. Gdn::FactoryInstall(Gdn::AliasPermissionModel, 'Gdn_PermissionModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.permissionmodel.php', Gdn::FactorySingleton); // Roles. Gdn::FactoryInstall('RoleModel', 'Gdn_RoleModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.rolemodel.php', Gdn::FactorySingleton); // Head. Gdn::FactoryInstall('Head', 'Gdn_HeadModule', PATH_APPLICATIONS . DS . 'garden' . DS . 'modules' . DS . 'class.headmodule.php', Gdn::FactorySingleton); // Menu. Gdn::FactoryInstall('Menu', 'Gdn_MenuModule', PATH_APPLICATIONS . DS . 'garden' . DS . 'modules' . DS . 'class.menumodule.php', Gdn::FactorySingleton); Gdn::Dispatcher()->PassProperty('Menu', Gdn::Factory('Menu')); // Search. Gdn::FactoryInstall('SearchModel', 'Gdn_SearchModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.searchmodel.php', Gdn::FactorySingleton);
/** * Configuration of registration settings. */ public function Registration($RedirectUrl = '') { $this->Permission('Garden.Registration.Manage'); if (!C('Garden.Registration.Manage', TRUE)) { return Gdn::Dispatcher()->Dispatch('Default404'); } $this->AddSideMenu('dashboard/settings/registration'); $this->AddJsFile('registration.js'); $this->Title(T('Registration')); // Create a model to save configuration settings $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigurationModel->SetField(array('Garden.Registration.Method' => 'Captcha', 'Garden.Registration.CaptchaPrivateKey', 'Garden.Registration.CaptchaPublicKey', 'Garden.Registration.InviteExpiration')); // Set the model on the forms. $this->Form->SetModel($ConfigurationModel); // Load roles with sign-in permission $RoleModel = new RoleModel(); $this->RoleData = $RoleModel->GetByPermission('Garden.SignIn.Allow'); // Get the currently selected default roles // $this->ExistingRoleData = Gdn::Config('Garden.Registration.DefaultRoles'); // if (is_array($this->ExistingRoleData) === FALSE) // $this->ExistingRoleData = array(); // Get currently selected InvitationOptions $this->ExistingRoleInvitations = Gdn::Config('Garden.Registration.InviteRoles'); if (is_array($this->ExistingRoleInvitations) === FALSE) { $this->ExistingRoleInvitations = array(); } // Get the currently selected Expiration Length $this->InviteExpiration = Gdn::Config('Garden.Registration.InviteExpiration', ''); // Registration methods. $this->RegistrationMethods = array('Captcha' => "New users fill out a simple form and are granted access immediately.", 'Approval' => "New users are reviewed and approved by an administrator (that's you!).", 'Invitation' => "Existing members send invitations to new members."); // Options for how many invitations a role can send out per month. $this->InvitationOptions = array('0' => T('None'), '1' => '1', '2' => '2', '5' => '5', '-1' => T('Unlimited')); // Options for when invitations should expire. $this->InviteExpirationOptions = array('-1 week' => T('1 week after being sent'), '-2 weeks' => T('2 weeks after being sent'), '-1 month' => T('1 month after being sent'), 'FALSE' => T('never')); if ($this->Form->AuthenticatedPostBack() === FALSE) { $this->Form->SetData($ConfigurationModel->Data); } else { // Define some validation rules for the fields being saved $ConfigurationModel->Validation->ApplyRule('Garden.Registration.Method', 'Required'); // if($this->Form->GetValue('Garden.Registration.Method') != 'Closed') // $ConfigurationModel->Validation->ApplyRule('Garden.Registration.DefaultRoles', 'RequiredArray'); // Define the Garden.Registration.RoleInvitations setting based on the postback values $InvitationRoleIDs = $this->Form->GetValue('InvitationRoleID'); $InvitationCounts = $this->Form->GetValue('InvitationCount'); $this->ExistingRoleInvitations = ArrayCombine($InvitationRoleIDs, $InvitationCounts); $ConfigurationModel->ForceSetting('Garden.Registration.InviteRoles', $this->ExistingRoleInvitations); // Save! if ($this->Form->Save() !== FALSE) { $this->StatusMessage = T("Your settings have been saved."); if ($RedirectUrl != '') { $this->RedirectUrl = $RedirectUrl; } } } $this->Render(); }
public function EntryController_Land_Create($Sender) { if (!Gdn::Authenticator()->IsPrimary('proxy')) { return; } $LandingRequest = Gdn_Request::Create()->FromImport(Gdn::Request())->WithURI("/dashboard/entry/signin")->WithCustomArgs(array('Landing' => TRUE)); return Gdn::Dispatcher()->Dispatch($LandingRequest); }
<?php // User. Gdn::FactoryInstall(Gdn::AliasUserModel, 'Gdn_UserModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.usermodel.php', Gdn::FactorySingleton); // Permissions. Gdn::FactoryInstall(Gdn::AliasPermissionModel, 'Gdn_PermissionModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.permissionmodel.php', Gdn::FactorySingleton); // Roles. Gdn::FactoryInstall('RoleModel', 'Gdn_RoleModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.rolemodel.php', Gdn::FactorySingleton); // Head. Gdn::FactoryInstall('Head', 'Gdn_HeadModule', PATH_APPLICATIONS . DS . 'garden' . DS . 'modules' . DS . 'class.headmodule.php', Gdn::FactorySingleton); // Menu. Gdn::FactoryInstall('Menu', 'Gdn_MenuModule', PATH_APPLICATIONS . DS . 'garden' . DS . 'modules' . DS . 'class.menumodule.php', Gdn::FactorySingleton); Gdn::Dispatcher()->PassProperty('Menu', Gdn::Factory('Menu')); // Search. Gdn::FactoryInstall('SearchModel', 'Gdn_SearchModel', PATH_APPLICATIONS . DS . 'garden' . DS . 'models' . DS . 'class.searchmodel.php', Gdn::FactorySingleton); Gdn::FactoryInstall('SearchModule', 'Gdn_SearchModule', PATH_APPLICATIONS . DS . 'garden' . DS . 'modules' . DS . 'class.searchmodule.php', Gdn::FactorySingleton); Gdn::Dispatcher()->PassAsset('Search', Gdn::Factory('SearchModule'));
/** * Shows all uncleared messages within a conversation for the viewing user * * @since 2.0.0 * @access public * * @param int $ConversationID Unique ID of conversation to view. * @param int $Offset Number to skip. * @param int $Limit Number to show. */ public function Index($ConversationID = FALSE, $Offset = -1, $Limit = '') { $this->Offset = $Offset; $Session = Gdn::Session(); // Figure out Conversation ID if (!is_numeric($ConversationID) || $ConversationID < 0) { $ConversationID = 0; } // Form setup for adding comments $this->Form->SetModel($this->ConversationMessageModel); $this->Form->AddHidden('ConversationID', $ConversationID); // Get conversation data $this->RecipientData = $this->ConversationModel->GetRecipients($ConversationID); $this->SetData('Recipients', $this->RecipientData); // Check permissions on the recipients. $InConversation = FALSE; foreach ($this->RecipientData->Result() as $Recipient) { if ($Recipient->UserID == Gdn::Session()->UserID) { $InConversation = TRUE; break; } } if (!$InConversation) { // Conversation moderation must be enabled and they must have permission if (!C('Conversations.Moderation.Allow', FALSE)) { Gdn::Dispatcher()->Dispatch('DefaultPermission'); exit; } $this->Permission('Conversations.Moderation.Manage'); } $this->Conversation = $this->ConversationModel->GetID($ConversationID); $this->SetData('Conversation', $this->Conversation); // Bad conversation? Redirect if ($this->Conversation === FALSE) { throw NotFoundException('Conversation'); } // Get limit if ($Limit == '' || !is_numeric($Limit) || $Limit < 0) { $Limit = Gdn::Config('Conversations.Messages.PerPage', 50); } // Calculate counts if (!is_numeric($this->Offset) || $this->Offset < 0) { // Round down to the appropriate offset based on the user's read messages & messages per page $CountReadMessages = $this->Conversation->CountMessages - $this->Conversation->CountNewMessages; if ($CountReadMessages < 0) { $CountReadMessages = 0; } if ($CountReadMessages > $this->Conversation->CountMessages) { $CountReadMessages = $this->Conversation->CountMessages; } // (((67 comments / 10 perpage) = 6.7) rounded down = 6) * 10 perpage = offset 60; $this->Offset = floor($CountReadMessages / $Limit) * $Limit; // Send the hash link in. if ($CountReadMessages > 1) { $this->AddDefinition('LocationHash', '#Item_' . $CountReadMessages); } } // Fetch message data $this->MessageData = $this->ConversationMessageModel->Get($ConversationID, $Session->UserID, $this->Offset, $Limit); // Figure out who's participating. $this->Participants = ''; $Count = 0; $Users = array(); $InConversation = FALSE; foreach ($this->RecipientData->Result() as $User) { $Count++; if ($User->UserID == $Session->UserID) { $InConversation = TRUE; continue; } if ($User->Deleted) { $Users[] = Wrap(UserAnchor($User), 'del', array('title' => sprintf(T('%s has left this conversation.'), htmlspecialchars($User->Name)))); $this->SetData('_HasDeletedUsers', TRUE); } else { $Users[] = UserAnchor($User); } } if ($InConversation) { if (count($Users) == 0) { $this->Participants = T('Just you!'); } else { $this->Participants = sprintf(T('%s and you'), implode(', ', $Users)); } } else { $this->Participants = implode(', ', $Users); } $this->Title(strip_tags($this->Participants)); // $CountMessages = $this->ConversationMessageModel->GetCount($ConversationID, $Session->UserID); // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->Pager = $PagerFactory->GetPager('MorePager', $this); $this->Pager->MoreCode = 'Newer Messages'; $this->Pager->LessCode = 'Older Messages'; $this->Pager->ClientID = 'Pager'; $this->Pager->Configure($this->Offset, $Limit, $this->Conversation->CountMessages, 'messages/' . $ConversationID . '/%1$s/%2$s/'); // Mark the conversation as ready by this user. $this->ConversationModel->MarkRead($ConversationID, $Session->UserID); // Deliver json data if necessary if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->SetJson('LessRow', $this->Pager->ToString('less')); $this->SetJson('MoreRow', $this->Pager->ToString('more')); $this->View = 'messages'; } // Add modules. $this->AddModule('SignedInModule'); $this->AddModule('NewConversationModule'); $ClearHistoryModule = new ClearHistoryModule($this); $ClearHistoryModule->ConversationID($ConversationID); $this->AddModule($ClearHistoryModule); $InThisConversationModule = new InThisConversationModule($this); $InThisConversationModule->SetData($this->RecipientData); $this->AddModule($InThisConversationModule); $this->AddModule('AddPeopleModule'); // Render view $this->Render(); }
/** * Create a new not found exception. This is a convenience function that will create an exception with a standard message. * * @param string $Code The translation code of the type of object that wasn't found. * @return Exception */ function NotFoundException($RecordType = 'Page') { Gdn::Dispatcher()->PassData('RecordType', $RecordType)->PassData('Description', sprintf(T('The %s you were looking for could not be found.'), strtolower($RecordType))); return new Gdn_UserException(sprintf(T('%s not found.'), T($RecordType)), 404); }
public function DiscussionsController_Render_Before($Sender) { if (!$this->Enabled()) { return; } $data = array(); switch (Gdn::Dispatcher()->ControllerMethod()) { case 'tagged': $type = 'tagged'; $data['tag'] = $Sender->Data('Tag'); break; case 'index': default: $type = 'discussions'; break; } $this->ParseTitle($Sender, $data, $type); }
/** * Render an exception as the sole output. * * @param Exception $Ex The exception to render. */ public function RenderException($Ex) { if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) { try { switch ($Ex->getCode()) { case 401: Gdn::Dispatcher()->Dispatch('DefaultPermission'); break; case 404: Gdn::Dispatcher()->Dispatch('Default404'); break; default: Gdn_ExceptionHandler($Ex); } } catch (Exception $Ex2) { Gdn_ExceptionHandler($Ex); } return; } // Make sure the database connection is closed before exiting. $this->Finalize(); $this->SendHeaders(); $Code = $Ex->getCode(); if (Debug()) { $Message = $Ex->getMessage() . "\n\n" . $Ex->getTraceAsString(); } else { $Message = $Ex->getMessage(); } if ($Code >= 100 && $Code <= 505) { header("HTTP/1.0 {$Code}", TRUE, $Code); } else { header('HTTP/1.0 500', TRUE, 500); } $Data = array('Code' => $Code, 'Exception' => $Message); switch ($this->DeliveryMethod()) { case DELIVERY_METHOD_JSON: header('Content-Type: application/json', TRUE); if ($Callback = $this->Request->GetValueFrom(Gdn_Request::INPUT_GET, 'callback', FALSE)) { // This is a jsonp request. exit($Callback . '(' . json_encode($Data) . ');'); } else { // This is a regular json request. exit(json_encode($Data)); } break; // case DELIVERY_METHOD_XHTML: // Gdn_ExceptionHandler($Ex); // break; // case DELIVERY_METHOD_XHTML: // Gdn_ExceptionHandler($Ex); // break; case DELIVERY_METHOD_XML: header('Content-Type: text/xml', TRUE); array_map('htmlspecialchars', $Data); exit("<Exception><Code>{$Data['Code']}</Code><Message>{$Data['Exception']}</Message></Exception>"); break; } }
protected function _AddEdit($Sender, $PocketID = FALSE) { $Form = new Gdn_Form(); $PocketModel = new Gdn_Model('Pocket'); $Form->SetModel($PocketModel); $Sender->ConditionModule = new ConditionModule($Sender); $Sender->Form = $Form; if ($Form->AuthenticatedPostBack()) { // Save the pocket. if ($PocketID !== FALSE) { $Form->SetFormValue('PocketID', $PocketID); } // Convert the form data into a format digestable by the database. $Repeat = $Form->GetFormValue('RepeatType'); switch ($Repeat) { case Pocket::REPEAT_EVERY: $PocketModel->Validation->ApplyRule('EveryFrequency', 'Integer'); $PocketModel->Validation->ApplyRule('EveryBegin', 'Integer'); $Frequency = $Form->GetFormValue('EveryFrequency', 1); if (!$Frequency || !ValidateInteger($Frequency) || $Frequency < 1) { $Frequency = 1; } $Repeat .= ' ' . $Frequency; if ($Form->GetFormValue('EveryBegin', 1) > 1) { $Repeat .= ',' . $Form->GetFormValue('EveryBegin'); } break; case Pocket::REPEAT_INDEX: $PocketModel->Validation->AddRule('IntegerArray', 'function:ValidateIntegerArray'); $PocketModel->Validation->ApplyRule('Indexes', 'IntegerArray'); $Indexes = explode(',', $Form->GetFormValue('Indexes', '')); $Indexes = array_map('trim', $Indexes); $Repeat .= ' ' . implode(',', $Indexes); break; default: break; } $Form->SetFormValue('Repeat', $Repeat); $Form->SetFormValue('Sort', 0); $Form->SetFormValue('Format', 'Raw'); $Condition = Gdn_Condition::ToString($Sender->ConditionModule->Conditions(TRUE)); $Form->SetFormValue('Condition', $Condition); if ($Form->GetFormValue('Ad', 0)) { $Form->SetFormValue('Type', Pocket::TYPE_AD); } else { $Form->SetFormValue('Type', Pocket::TYPE_DEFAULT); } $Saved = $Form->Save(); if ($Saved) { $Sender->StatusMessage = T('Your changes have been saved.'); $Sender->RedirectUrl = Url('settings/pockets'); } } else { if ($PocketID !== FALSE) { // Load the pocket. $Pocket = $PocketModel->GetWhere(array('PocketID' => $PocketID))->FirstRow(DATASET_TYPE_ARRAY); if (!$Pocket) { return Gdn::Dispatcher()->Dispatch('Default404'); } // Convert some of the pocket data into a format digestable by the form. list($RepeatType, $RepeatFrequency) = Pocket::ParseRepeat($Pocket['Repeat']); $Pocket['RepeatType'] = $RepeatType; $Pocket['EveryFrequency'] = GetValue(0, $RepeatFrequency, 1); $Pocket['EveryBegin'] = GetValue(1, $RepeatFrequency, 1); $Pocket['Indexes'] = implode(',', $RepeatFrequency); $Pocket['Ad'] = $Pocket['Type'] == Pocket::TYPE_AD; $Sender->ConditionModule->Conditions(Gdn_Condition::FromString($Pocket['Condition'])); $Form->SetData($Pocket); } else { // Default the repeat. $Form->SetFormValue('RepeatType', Pocket::REPEAT_ONCE); } } $Sender->Form = $Form; $Sender->SetData('Locations', $this->Locations); $Sender->SetData('LocationsArray', $this->GetLocationsArray()); $Sender->SetData('Pages', array('' => '(' . T('All') . ')', 'activity' => 'activity', 'comments' => 'comments', 'dashboard' => 'dashboard', 'discussions' => 'discussions', 'inbox' => 'inbox', 'profile' => 'profile')); return $Sender->Render('AddEdit', '', 'plugins/Pockets'); }
/** * Create a controller and initialize it with data from the dispatcher. * * @param string $controllerName The name of the controller to create. * @param Gdn_Request $request The current request. * @param array &$routeArgs Arguments from a call to {@link Gdn_Dispatcher::analyzeRequest}. * @return Gdn_Controller Returns a new {@link Gdn_Controller} object. */ private function createController($controllerName, $request, &$routeArgs) { /* @var Gdn_Controller $controller */ $controller = new $controllerName(); Gdn::controller($controller); $this->EventArguments['Controller'] =& $controller; $this->fireEvent('AfterControllerCreate'); // Pass along any assets if (is_array($this->controllerAssets)) { foreach ($this->controllerAssets as $AssetName => $Assets) { foreach ($Assets as $Asset) { $controller->addAsset($AssetName, $Asset); } } } // Instantiate Imported & Uses classes $controller->getImports(); // Pass along any objects foreach ($this->controllerProperties as $Name => $Mixed) { $controller->{$Name} = $Mixed; } // Pass along any data. if (!empty($this->controllerData)) { $controller->Data = $this->controllerData; } $controller->Request = $request; $controller->SelfUrl = $routeArgs['path']; /* @var Addon $addon */ $addon = $routeArgs['addon']; if ($addon) { $controller->Application = $addon->getKey(); $controller->ApplicationFolder = stringBeginsWith(ltrim($addon->getSubdir(), '/'), 'applications/', true, true); } $controller->Request = $request; $controller->deliveryType($routeArgs['deliveryType']); $controller->deliveryMethod($routeArgs['deliveryMethod']); $controller->SyndicationMethod = val('syndicationMethod', $routeArgs, SYNDICATION_NONE); $this->deliveryType = $routeArgs['deliveryType']; $this->deliveryMethod = $routeArgs['deliveryMethod']; // Kludge: We currently have a couple of plugins that modify the path arguments on initialize. $this->controllerArguments($routeArgs['pathArgs']); // End kludge. $controller->initialize(); // Kludge for controllers that modify the dispatcher. $pathArgs = $this->controllerArguments(); if (!empty($this->ControllerMethod)) { array_unshift($pathArgs, Gdn::Dispatcher()->ControllerMethod); } $routeArgs['pathArgs'] = $pathArgs; // End kluge. $this->EventArguments['Controller'] = $controller; $this->fireEvent('AfterControllerInit'); return $controller; }
public function rootController_sso_handler($Sender, $Args) { $Provider = $Args['DefaultProvider']; if (GetValue('AuthenticationSchemeAlias', $Provider) !== 'jsconnect') { return; } // The default provider is jsconnect so let's redispatch there. $Get = array('client_id' => GetValue('AuthenticationKey', $Provider), 'target' => GetValue('Target', $Args, '/')); $Url = '/entry/jsconnect?' . http_build_query($Get); Gdn::Request()->PathAndQuery($Url); Gdn::Dispatcher()->Dispatch(); $Args['Handled'] = TRUE; }
public function SyncScreen($Authenticator, $UserInfo, $Payload) { $this->AddJsFile('entry.js'); $this->View = 'handshake'; $this->HandshakeScheme = $Authenticator->GetAuthenticationSchemeAlias(); $this->Form->SetModel($this->UserModel); $this->Form->AddHidden('ClientHour', date('G', time())); // Use the server's current hour as a default $this->Form->AddHidden('Target', GetIncomingValue('Target', '/')); $PreservedKeys = array('UserKey', 'Token', 'Consumer', 'Email', 'Name', 'Gender', 'HourOffset'); $UserID = 0; $Target = GetIncomingValue('Target', '/'); if ($this->Form->IsPostBack() === TRUE) { $FormValues = $this->Form->FormValues(); if (ArrayValue('StopLinking', $FormValues)) { $Authenticator->DeleteCookie(); Gdn::Request()->WithRoute('DefaultController'); return Gdn::Dispatcher()->Dispatch(); } elseif (ArrayValue('NewAccount', $FormValues)) { // Try and synchronize the user with the new username/email. $FormValues['Name'] = $FormValues['NewName']; $FormValues['Email'] = $FormValues['NewEmail']; $UserID = $this->UserModel->Synchronize($UserInfo['UserKey'], $FormValues); $this->Form->SetValidationResults($this->UserModel->ValidationResults()); } else { // Try and sign the user in. $PasswordAuthenticator = Gdn::Authenticator()->AuthenticateWith('password'); $PasswordAuthenticator->HookDataField('Email', 'SignInEmail'); $PasswordAuthenticator->HookDataField('Password', 'SignInPassword'); $PasswordAuthenticator->FetchData($this->Form); $UserID = $PasswordAuthenticator->Authenticate(); if ($UserID < 0) { $this->Form->AddError('ErrorPermission'); } else { if ($UserID == 0) { $this->Form->AddError('ErrorCredentials'); } } if ($UserID > 0) { $Data = $FormValues; $Data['UserID'] = $UserID; $Data['Email'] = ArrayValue('SignInEmail', $FormValues, ''); $UserID = $this->UserModel->Synchronize($UserInfo['UserKey'], $Data); } } if ($UserID > 0) { // The user has been created successfully, so sign in now // Finalize the link between the forum user and the foreign userkey $Authenticator->Finalize($UserInfo['UserKey'], $UserID, $UserInfo['ConsumerKey'], $UserInfo['TokenKey'], $Payload); /// ... and redirect them appropriately $Route = $this->RedirectTo(); if ($Route !== FALSE) { Redirect($Route); } } else { // Add the hidden inputs back into the form. foreach ($FormValues as $Key => $Value) { if (in_array($Key, $PreservedKeys)) { $this->Form->AddHidden($Key, $Value); } } } } else { $Id = Gdn::Authenticator()->GetIdentity(TRUE); if ($Id > 0) { // The user is signed in so we can just go back to the homepage. Redirect($Target); } $Name = $UserInfo['UserName']; $Email = $UserInfo['UserEmail']; // Set the defaults for a new user. $this->Form->SetFormValue('NewName', $Name); $this->Form->SetFormValue('NewEmail', $Email); // Set the default for the login. $this->Form->SetFormValue('SignInEmail', $Email); $this->Form->SetFormValue('Handshake', 'NEW'); // Add the handshake data as hidden fields. $this->Form->AddHidden('Name', $Name); $this->Form->AddHidden('Email', $Email); $this->Form->AddHidden('UserKey', $UserInfo['UserKey']); $this->Form->AddHidden('Token', $UserInfo['TokenKey']); $this->Form->AddHidden('Consumer', $UserInfo['ConsumerKey']); } $this->SetData('Name', ArrayValue('Name', $this->Form->HiddenInputs)); $this->SetData('Email', ArrayValue('Email', $this->Form->HiddenInputs)); $this->Render(); }
public function DiscussionsController_Render_Before($Sender) { if (!$this->Enabled()) { return; } $data = array(); switch (Gdn::Dispatcher()->ControllerMethod()) { // We don't need these personal pages yet because no Search Engines visit them. /* case 'mine': $type = 'my_discussions'; break; case 'bookmarked': $type = 'bookmarked_discussions'; break; */ case 'index': default: $type = 'discussions'; break; } $this->ParseTitle($Sender, $data, $type); }