/** * Allows the configuration of basic setup information in Garden. This * should not be functional after the application has been set up. * * @since 2.0.0 * @access public * @param string $RedirectUrl Where to send user afterward. */ public function Configure($RedirectUrl = '') { // Create a model to save configuration settings $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigurationModel->SetField(array('Garden.Locale', 'Garden.Title', 'Garden.RewriteUrls', 'Garden.WebRoot', 'Garden.Cookie.Salt', 'Garden.Cookie.Domain', 'Database.Name', 'Database.Host', 'Database.User', 'Database.Password', 'Garden.Registration.ConfirmEmail', 'Garden.Email.SupportName')); // Set the models on the forms. $this->Form->SetModel($ConfigurationModel); // Load the locales for the locale dropdown // $Locale = Gdn::Locale(); // $AvailableLocales = $Locale->GetAvailableLocaleSources(); // $this->LocaleData = array_combine($AvailableLocales, $AvailableLocales); // If seeing the form for the first time... if (!$this->Form->IsPostback()) { // Force the webroot using our best guesstimates $ConfigurationModel->Data['Database.Host'] = 'localhost'; $this->Form->SetData($ConfigurationModel->Data); } else { // Define some validation rules for the fields being saved $ConfigurationModel->Validation->ApplyRule('Database.Name', 'Required', 'You must specify the name of the database in which you want to set up Vanilla.'); // Let's make some user-friendly custom errors for database problems $DatabaseHost = $this->Form->GetFormValue('Database.Host', '~~Invalid~~'); $DatabaseName = $this->Form->GetFormValue('Database.Name', '~~Invalid~~'); $DatabaseUser = $this->Form->GetFormValue('Database.User', '~~Invalid~~'); $DatabasePassword = $this->Form->GetFormValue('Database.Password', '~~Invalid~~'); $ConnectionString = GetConnectionString($DatabaseName, $DatabaseHost); try { $Connection = new PDO($ConnectionString, $DatabaseUser, $DatabasePassword); } catch (PDOException $Exception) { switch ($Exception->getCode()) { case 1044: $this->Form->AddError(T('The database user you specified does not have permission to access the database. Have you created the database yet? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 1045: $this->Form->AddError(T('Failed to connect to the database with the username and password you entered. Did you mistype them? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 1049: $this->Form->AddError(T('It appears as though the database you specified does not exist yet. Have you created it yet? Did you mistype the name? The database reported: <code>%s</code>'), strip_tags($Exception->getMessage())); break; case 2005: $this->Form->AddError(T("Are you sure you've entered the correct database host name? Maybe you mistyped it? The database reported: <code>%s</code>"), strip_tags($Exception->getMessage())); break; default: $this->Form->AddError(sprintf(T('ValidateConnection'), strip_tags($Exception->getMessage()))); break; } } $ConfigurationModel->Validation->ApplyRule('Garden.Title', 'Required'); $ConfigurationFormValues = $this->Form->FormValues(); if ($ConfigurationModel->Validate($ConfigurationFormValues) !== TRUE || $this->Form->ErrorCount() > 0) { // Apply the validation results to the form(s) $this->Form->SetValidationResults($ConfigurationModel->ValidationResults()); } else { $Host = array_shift(explode(':', Gdn::Request()->RequestHost())); $Domain = Gdn::Request()->Domain(); // Set up cookies now so that the user can be signed in. $ExistingSalt = C('Garden.Cookie.Salt', FALSE); $ConfigurationFormValues['Garden.Cookie.Salt'] = $ExistingSalt ? $ExistingSalt : RandomString(10); $ConfigurationFormValues['Garden.Cookie.Domain'] = ''; // Don't set this to anything by default. # Tim - 2010-06-23 // Additional default setup values. $ConfigurationFormValues['Garden.Registration.ConfirmEmail'] = TRUE; $ConfigurationFormValues['Garden.Email.SupportName'] = $ConfigurationFormValues['Garden.Title']; $ConfigurationModel->Save($ConfigurationFormValues, TRUE); // If changing locale, redefine locale sources: $NewLocale = 'en-CA'; // $this->Form->GetFormValue('Garden.Locale', FALSE); if ($NewLocale !== FALSE && Gdn::Config('Garden.Locale') != $NewLocale) { $ApplicationManager = new Gdn_ApplicationManager(); $Locale = Gdn::Locale(); $Locale->Set($NewLocale, $ApplicationManager->EnabledApplicationFolders(), Gdn::PluginManager()->EnabledPluginFolders(), TRUE); } // Install db structure & basic data. $Database = Gdn::Database(); $Database->Init(); $Drop = FALSE; // Gdn::Config('Garden.Version') === FALSE ? TRUE : FALSE; $Explicit = FALSE; try { include PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'structure.php'; } catch (Exception $ex) { $this->Form->AddError($ex); } if ($this->Form->ErrorCount() > 0) { return FALSE; } // Create the administrative user $UserModel = Gdn::UserModel(); $UserModel->DefineSchema(); $UsernameError = T('UsernameError', 'Username can only contain letters, numbers, underscores, and must be between 3 and 20 characters long.'); $UserModel->Validation->ApplyRule('Name', 'Username', $UsernameError); $UserModel->Validation->ApplyRule('Name', 'Required', T('You must specify an admin username.')); $UserModel->Validation->ApplyRule('Password', 'Required', T('You must specify an admin password.')); $UserModel->Validation->ApplyRule('Password', 'Match'); $UserModel->Validation->ApplyRule('Email', 'Email'); if (!($AdminUserID = $UserModel->SaveAdminUser($ConfigurationFormValues))) { $this->Form->SetValidationResults($UserModel->ValidationResults()); } else { // The user has been created successfully, so sign in now. SaveToConfig('Garden.Installed', TRUE, array('Save' => FALSE)); Gdn::Session()->Start($AdminUserID, TRUE); SaveToConfig('Garden.Installed', FALSE, array('Save' => FALSE)); } if ($this->Form->ErrorCount() > 0) { return FALSE; } // Assign some extra settings to the configuration file if everything succeeded. $ApplicationInfo = array(); include CombinePaths(array(PATH_APPLICATIONS . DS . 'dashboard' . DS . 'settings' . DS . 'about.php')); // Detect rewrite abilities try { $Query = ConcatSep('/', Gdn::Request()->Domain(), Gdn::Request()->WebRoot(), 'dashboard/setup'); $Results = ProxyHead($Query, array(), 3); $CanRewrite = FALSE; if (in_array(ArrayValue('StatusCode', $Results, 404), array(200, 302)) && ArrayValue('X-Garden-Version', $Results, 'None') != 'None') { $CanRewrite = TRUE; } } catch (Exception $e) { // cURL and fsockopen arent supported... guess? $CanRewrite = function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules()) ? TRUE : FALSE; } SaveToConfig(array('Garden.Version' => ArrayValue('Version', GetValue('Dashboard', $ApplicationInfo, array()), 'Undefined'), 'Garden.RewriteUrls' => $CanRewrite, 'Garden.CanProcessImages' => function_exists('gd_info'), 'EnabledPlugins.GettingStarted' => 'GettingStarted', 'EnabledPlugins.HtmLawed' => 'HtmLawed')); } } return $this->Form->ErrorCount() == 0 ? TRUE : FALSE; }
function ProxyHead($Url, $Headers = NULL, $Timeout = FALSE, $FollowRedirects = FALSE) { if (is_null($Headers)) { $Headers = array(); } $OriginalHeaders = $Headers; $OriginalTimeout = $Timeout; if (!$Timeout) { $Timeout = C('Garden.SocketTimeout', 1.0); } $UrlParts = parse_url($Url); $Scheme = GetValue('scheme', $UrlParts, 'http'); $Host = GetValue('host', $UrlParts, ''); $Port = GetValue('port', $UrlParts, '80'); $Path = GetValue('path', $UrlParts, ''); $Query = GetValue('query', $UrlParts, ''); // Get the cookie. $Cookie = ''; $EncodeCookies = C('Garden.Cookie.Urlencode', TRUE); foreach ($_COOKIE as $Key => $Value) { if (strncasecmp($Key, 'XDEBUG', 6) == 0) { continue; } if (strlen($Cookie) > 0) { $Cookie .= '; '; } $EValue = $EncodeCookies ? urlencode($Value) : $Value; $Cookie .= "{$Key}={$EValue}"; } $Cookie = array('Cookie' => $Cookie); $Response = ''; if (function_exists('curl_init')) { //$Url = $Scheme.'://'.$Host.$Path; $Handler = curl_init(); curl_setopt($Handler, CURLOPT_TIMEOUT, $Timeout); curl_setopt($Handler, CURLOPT_URL, $Url); curl_setopt($Handler, CURLOPT_PORT, $Port); curl_setopt($Handler, CURLOPT_HEADER, 1); curl_setopt($Handler, CURLOPT_NOBODY, 1); curl_setopt($Handler, CURLOPT_USERAGENT, ArrayValue('HTTP_USER_AGENT', $_SERVER, 'Vanilla/2.0')); curl_setopt($Handler, CURLOPT_RETURNTRANSFER, 1); curl_setopt($Handler, CURLOPT_HTTPHEADER, $Headers); if (strlen($Cookie['Cookie'])) { curl_setopt($Handler, CURLOPT_COOKIE, $Cookie['Cookie']); } //if ($Query != '') { // curl_setopt($Handler, CURLOPT_POST, 1); // curl_setopt($Handler, CURLOPT_POSTFIELDS, $Query); //} $Response = curl_exec($Handler); if ($Response == FALSE) { $Response = curl_error($Handler); } curl_close($Handler); } else { if (function_exists('fsockopen')) { $Referer = Gdn::Request()->WebRoot(); // Make the request $Pointer = @fsockopen($Host, $Port, $ErrorNumber, $Error, $Timeout); if (!$Pointer) { throw new Exception(sprintf(T('Encountered an error while making a request to the remote server (%1$s): [%2$s] %3$s'), $Url, $ErrorNumber, $Error)); } $Request = "HEAD {$Path}?{$Query} HTTP/1.1\r\n"; $HostHeader = $Host . ($Post != 80) ? ":{$Port}" : ''; $Header = array('Host' => $HostHeader, 'User-Agent' => ArrayValue('HTTP_USER_AGENT', $_SERVER, 'Vanilla/2.0'), 'Accept' => '*/*', 'Accept-Charset' => 'utf-8', 'Referer' => $Referer, 'Connection' => 'close'); if (strlen($Cookie['Cookie'])) { $Header = array_merge($Header, $Cookie); } $Header = array_merge($Header, $Headers); $HeaderString = ""; foreach ($Header as $HeaderName => $HeaderValue) { $HeaderString .= "{$HeaderName}: {$HeaderValue}\r\n"; } $HeaderString .= "\r\n"; // Send the headers and get the response fputs($Pointer, $Request); fputs($Pointer, $HeaderString); while ($Line = fread($Pointer, 4096)) { $Response .= $Line; } @fclose($Pointer); $Response = trim($Response); } else { throw new Exception(T('Encountered an error while making a request to the remote server: Your PHP configuration does not allow curl or fsock requests.')); } } $ResponseLines = explode("\n", trim($Response)); $Status = array_shift($ResponseLines); $Response = array(); $Response['HTTP'] = trim($Status); /* get the numeric status code. * - trim off excess edge whitespace, * - split on spaces, * - get the 2nd element (as a single element array), * - pop the first (only) element off it... * - return that. */ $Response['StatusCode'] = array_pop(array_slice(explode(' ', trim($Status)), 1, 1)); foreach ($ResponseLines as $Line) { $Line = explode(':', trim($Line)); $Key = trim(array_shift($Line)); $Value = trim(implode(':', $Line)); $Response[$Key] = $Value; } if ($FollowRedirects) { $Code = GetValue('StatusCode', $Response, 200); if (in_array($Code, array(301, 302))) { if (array_key_exists('Location', $Response)) { $Location = GetValue('Location', $Response); return ProxyHead($Location, $OriginalHeaders, $OriginalTimeout, $FollowRedirects); } } } return $Response; }
protected function QueryRemote($Provider, $Task, $Arguments = NULL, $Secure = TRUE, $GetBody = FALSE) { if (!is_array($Arguments)) { $Arguments = array(); } $Arguments = array_merge($Arguments, array('ProxyConnectAutoconfigure' => 'configure', 'Task' => $Task)); if ($Secure) { $Arguments = array_merge($Arguments, array('Key' => GetValue('AssociationSecret', $Provider))); } $RealURL = GetValue('URL', $Provider) . "?" . http_build_query($Arguments); if ($GetBody) { return ProxyRequest($RealURL, FALSE, TRUE); } else { return ProxyHead($RealURL, NULL, FALSE, TRUE); } }