diff --git a/.travis.yml b/.travis.yml index 29b699477..8c9e95d9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,9 +62,6 @@ before_script: - phpenv config-rm xdebug.ini || true - echo 'memory_limit = 2048M' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini -# Temporarily update to 1.5.x-dev of composer - - composer self-update --snapshot - # Install composer dependencies - export PATH=~/.composer/vendor/bin:$PATH - composer validate diff --git a/phpcs.xml.dist b/phpcs.xml.dist index d02ea6b00..b2ed50871 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -19,6 +19,9 @@ + + + */SSTemplateParser.php$ */_fakewebroot/* diff --git a/src/Dev/Install/InstallConfig.php b/src/Dev/Install/InstallConfig.php new file mode 100644 index 000000000..6be632b15 --- /dev/null +++ b/src/Dev/Install/InstallConfig.php @@ -0,0 +1,245 @@ + $type ], + $request['db'][$type] + ); + } + } + + // Guess database config + return [ + 'type' => $this->getDatabaseClass($databaseClasses), + 'server' => getenv('SS_DATABASE_SERVER') ?: 'localhost', + 'username' => getenv('SS_DATABASE_USERNAME') ?: 'root', + 'password' => getenv('SS_DATABASE_PASSWORD') ?: '', + 'database' => getenv('SS_DATABASE_NAME') ?: 'SS_mysite', + ]; + } + + /** + * Get admin config from the environment + * + * @param array $request + * @return array + */ + public function getAdminConfig($request) + { + if (isset($request['admin'])) { + return $request['admin']; + } + + return [ + 'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin', + 'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '', + ]; + } + + /** + * Check if this site has already been installed + * + * @return bool + */ + public function alreadyInstalled() + { + if (file_exists($this->getEnvPath())) { + return true; + } + if (!file_exists($this->getConfigPath())) { + return false; + } + $configContents = file_get_contents($this->getConfigPath()); + if (strstr($configContents, '$databaseConfig')) { + return true; + } + if (strstr($configContents, '$database')) { + return true; + } + return false; + } + + /** + * @return string + */ + protected function getConfigPath() + { + return BASE_PATH . '/mysite/_config.php'; + } + + /** + * @return string + */ + protected function getEnvPath() + { + return BASE_PATH . '/.env'; + } + + /** + * Database configs available for configuration + * + * @param array $databaseClasses + * @return string + */ + protected function getDatabaseClass($databaseClasses) + { + if (getenv('SS_DATABASE_CLASS')) { + return getenv('SS_DATABASE_CLASS'); + } + + // Check supported versions + foreach ($this->preferredDatabases as $candidate) { + if (!empty($databaseClasses[$candidate]['supported'])) { + return $candidate; + } + } + return null; + } + + /** + * Get string representation of the framework version + * + * @return string + */ + public function getFrameworkVersion() + { + $composerLockPath = BASE_PATH . '/composer.lock'; + if (!file_exists($composerLockPath)) { + return 'unknown'; + } + $lockData = json_decode(file_get_contents($composerLockPath), true); + if (json_last_error() || empty($lockData['packages'])) { + return 'unknown'; + } + foreach ($lockData['packages'] as $package) { + if ($package['name'] === 'silverstripe/framework') { + return $package['version']; + } + } + return 'unknown'; + } + + /** + * Check if stats should be sent + * + * @param array $request + * @return bool + */ + public function canSendStats($request) + { + return !empty($request['stats']); + } + + /** + * Get configured locales + * + * @return array + */ + public function getLocales() + { + return [ + 'af_ZA' => 'Afrikaans (South Africa)', + 'ar_EG' => 'Arabic (Egypt)', + 'hy_AM' => 'Armenian (Armenia)', + 'ast_ES' => 'Asturian (Spain)', + 'az_AZ' => 'Azerbaijani (Azerbaijan)', + 'bs_BA' => 'Bosnian (Bosnia and Herzegovina)', + 'bg_BG' => 'Bulgarian (Bulgaria)', + 'ca_ES' => 'Catalan (Spain)', + 'zh_CN' => 'Chinese (China)', + 'zh_TW' => 'Chinese (Taiwan)', + 'hr_HR' => 'Croatian (Croatia)', + 'cs_CZ' => 'Czech (Czech Republic)', + 'da_DK' => 'Danish (Denmark)', + 'nl_NL' => 'Dutch (Netherlands)', + 'en_GB' => 'English (United Kingdom)', + 'en_US' => 'English (United States)', + 'eo_XX' => 'Esperanto', + 'et_EE' => 'Estonian (Estonia)', + 'fo_FO' => 'Faroese (Faroe Islands)', + 'fi_FI' => 'Finnish (Finland)', + 'fr_FR' => 'French (France)', + 'de_DE' => 'German (Germany)', + 'el_GR' => 'Greek (Greece)', + 'he_IL' => 'Hebrew (Israel)', + 'hu_HU' => 'Hungarian (Hungary)', + 'is_IS' => 'Icelandic (Iceland)', + 'id_ID' => 'Indonesian (Indonesia)', + 'it_IT' => 'Italian (Italy)', + 'ja_JP' => 'Japanese (Japan)', + 'km_KH' => 'Khmer (Cambodia)', + 'lc_XX' => 'LOLCAT', + 'lv_LV' => 'Latvian (Latvia)', + 'lt_LT' => 'Lithuanian (Lithuania)', + 'ms_MY' => 'Malay (Malaysia)', + 'mi_NZ' => 'Maori (New Zealand)', + 'ne_NP' => 'Nepali (Nepal)', + 'nb_NO' => 'Norwegian', + 'fa_IR' => 'Persian (Iran)', + 'pl_PL' => 'Polish (Poland)', + 'pt_BR' => 'Portuguese (Brazil)', + 'pa_IN' => 'Punjabi (India)', + 'ro_RO' => 'Romanian (Romania)', + 'ru_RU' => 'Russian (Russia)', + 'sr_RS' => 'Serbian (Serbia)', + 'si_LK' => 'Sinhalese (Sri Lanka)', + 'sk_SK' => 'Slovak (Slovakia)', + 'sl_SI' => 'Slovenian (Slovenia)', + 'es_AR' => 'Spanish (Argentina)', + 'es_MX' => 'Spanish (Mexico)', + 'es_ES' => 'Spanish (Spain)', + 'sv_SE' => 'Swedish (Sweden)', + 'th_TH' => 'Thai (Thailand)', + 'tr_TR' => 'Turkish (Turkey)', + 'uk_UA' => 'Ukrainian (Ukraine)', + 'uz_UZ' => 'Uzbek (Uzbekistan)', + 'vi_VN' => 'Vietnamese (Vietnam)', + ]; + } + + /** + * Get theme selected + * + * @param $request + * @return string + */ + public function getTheme($request) + { + if (isset($request['template'])) { + return $request['template']; + } + // Default theme + return 'simple'; + } +} diff --git a/src/Dev/Install/InstallRequirements.php b/src/Dev/Install/InstallRequirements.php index 1cdc46ee7..be28fbcf4 100644 --- a/src/Dev/Install/InstallRequirements.php +++ b/src/Dev/Install/InstallRequirements.php @@ -50,17 +50,22 @@ class InstallRequirements return false; } + $path = empty($databaseConfig['path']) ? null : $databaseConfig['path']; + $server = empty($databaseConfig['server']) ? null : $databaseConfig['server']; + // Check if the server is available - $usePath = !empty($databaseConfig['path']) && empty($databaseConfig['server']); + $usePath = $path && empty($server); if (!$this->requireDatabaseServer( $databaseConfig, array( "Database Configuration", "Database server", $usePath - ? "I couldn't write to path '$databaseConfig[path]'" - : "I couldn't find a database server on '$databaseConfig[server]'", - $usePath ? $databaseConfig['path'] : $databaseConfig['server'] + ? "I couldn't write to path '{$path}'" + : "I couldn't find a database server on '{$server}'", + $usePath + ? $path + : $server ) ) ) { diff --git a/src/Dev/Install/Installer.php b/src/Dev/Install/Installer.php index 0d2881bd8..303a6bfe2 100644 --- a/src/Dev/Install/Installer.php +++ b/src/Dev/Install/Installer.php @@ -2,6 +2,7 @@ namespace SilverStripe\Dev\Install; +use Dotenv\Dotenv; use Exception; use SilverStripe\Control\Cookie; use SilverStripe\Control\HTTPApplication; @@ -15,7 +16,6 @@ use SilverStripe\Security\DefaultAdminService; use SilverStripe\Security\Security; /** - * SilverStripe CMS SilverStripe\Dev\Install\Installer * This installer doesn't use any of the fancy SilverStripe stuff in case it's unsupported. */ class Installer extends InstallRequirements @@ -67,41 +67,17 @@ class Installer extends InstallRequirements // Render header $this->installHeader(); - $webserver = $this->findWebserver(); $isIIS = $this->isIIS(); $isApache = $this->isApache(); flush(); - if (isset($config['stats'])) { - if (file_exists(FRAMEWORK_PATH . '/silverstripe_version')) { - $silverstripe_version = file_get_contents(FRAMEWORK_PATH . '/silverstripe_version'); - } else { - $silverstripe_version = "unknown"; - } - - $phpVersion = urlencode(phpversion()); - $encWebserver = urlencode($webserver); - $dbType = $config['db']['type']; - - // Try to determine the database version from the helper - $databaseVersion = $config['db']['type']; - $helper = $this->getDatabaseConfigurationHelper($dbType); - if ($helper && method_exists($helper, 'getDatabaseVersion')) { - $versionConfig = $config['db'][$dbType]; - $versionConfig['type'] = $dbType; - $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($versionConfig)); - } - - $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$encWebserver"; - - if (isset($_SESSION['StatsID']) && $_SESSION['StatsID']) { - $url .= '&ID=' . $_SESSION['StatsID']; - } - - @$_SESSION['StatsID'] = file_get_contents($url); + // Send install stats + if (!empty($config['stats'])) { + $this->sendInstallStats($config); } + // Cleanup _config.php if (file_exists('mysite/_config.php')) { // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them @@ -109,69 +85,12 @@ class Installer extends InstallRequirements fclose($fh); } - // Escape user input for safe insertion into PHP file - $theme = isset($_POST['template']) ? addcslashes($_POST['template'], "\'") : 'simple'; - $locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\'") : 'en_US'; - $type = addcslashes($config['db']['type'], "\'"); - $dbConfig = $config['db'][$type]; - foreach ($dbConfig as &$configValue) { - $configValue = addcslashes($configValue, "\\\'"); - } - if (!isset($dbConfig['path'])) { - $dbConfig['path'] = ''; - } - if (!$dbConfig) { - echo "

Bad config submitted

";
-            print_r($config);
-            echo "
"; - die(); - } - - // Write the config file - global $usingEnv; - if ($usingEnv) { - $this->statusMessage("Setting up 'mysite/_config.php' for use with environment variables..."); - $this->writeToFile("mysite/_config.php", "statusMessage("Setting up 'mysite/_config.php'..."); - // Create databaseConfig - $lines = array( - $lines[] = " 'type' => '$type'" - ); - foreach ($dbConfig as $key => $value) { - $lines[] = " '{$key}' => '$value'"; - } - $databaseConfigContent = implode(",\n", $lines); - $this->writeToFile("mysite/_config.php", <<statusMessage("Setting up 'mysite/_config/theme.yml'"); - $this->writeToFile("mysite/_config/theme.yml", <<writeConfigPHP($config); + $this->writeConfigYaml($config); + $this->writeConfigEnv($config); + // Write other stuff if (!$this->checkModuleExists('cms')) { $this->writeToFile("mysite/code/RootURLController.php", <<hasRewritingCapability()) { if ($isApache) { - $this->statusMessage("Setting up '.htaccess' file..."); $this->createHtaccess(); } elseif ($isIIS) { - $this->statusMessage("Setting up 'web.config' file..."); $this->createWebConfig(); } } @@ -282,18 +199,187 @@ HTML; return $this->errors; } + /** + * Write all .env files + * + * @param $config + */ + protected function writeConfigEnv($config) + { + if (!$config['usingEnv']) { + return; + } + + $path = $this->getBaseDir() . '.env'; + $vars = []; + + // Retain existing vars + // Note: vars with # or " in them are discarded + if (file_exists($path)) { + $env = new Dotenv($this->getBaseDir()); + foreach ($env->load() as $line) { + if (preg_match('/^(?\w+)\s*=\s*("?)(?[^"#]*)("?)$/', $line, $matches)) { + $vars[$matches['key']] = $matches['value']; + } + } + } + + // Set base URL + if (!isset($vars['SS_BASE_URL']) && isset($_SERVER['HTTP_HOST'])) { + $vars['SS_BASE_URL'] = 'http://' . $_SERVER['HTTP_HOST'] . BASE_URL; + } + + // Set DB env + if (empty($config['db']['database'])) { + $vars['SS_DATABASE_CHOOSE_NAME'] = true; + } else { + $vars['SS_DATABASE_NAME'] = $config['db']['database']; + } + $vars['SS_DATABASE_CLASS'] = $config['db']['type']; + if (isset($config['db']['server'])) { + $vars['SS_DATABASE_SERVER'] = $config['db']['server']; + } + if (isset($config['db']['username'])) { + $vars['SS_DATABASE_USERNAME'] = $config['db']['username']; + } + if (isset($config['db']['password'])) { + $vars['SS_DATABASE_PASSWORD'] = $config['db']['password']; + } + if (isset($config['db']['path'])) { + $vars['SS_DATABASE_PATH'] = $config['db']['path']; + // sqlite compat + $vars['SS_SQLITE_DATABASE_PATH'] = $config['db']['path']; + } + if (isset($config['db']['key'])) { + $vars['SS_DATABASE_KEY'] = $config['db']['key']; + // sqlite compat + $vars['SS_SQLITE_DATABASE_KEY'] = $config['db']['key']; + } + + // Write all env vars + $lines = [ + '# Generated by SilverStripe Installer' + ]; + ksort($vars); + foreach ($vars as $key => $value) { + $lines[] = $key.'="'.addcslashes($value, '"').'"'; + } + + $this->writeToFile('.env', implode("\n", $lines)); + + // Re-load env vars for installer access + $path = $this->getBaseDir(); + (new Dotenv($path))->load(); + } + + /** + * Write all *.php files + * + * @param array $config + */ + protected function writeConfigPHP($config) + { + if ($config['usingEnv']) { + $this->writeToFile("mysite/_config.php", " $value) { + $lines[] = sprintf( + " '%s' => '%s'", + addslashes($key), + addslashes($value) + ); + } + $databaseConfigContent = implode(",\n", $lines); + $this->writeToFile("mysite/_config.php", <<ymlString($config['locale']); + + // Set either specified, or no theme + if ($config['theme'] && $config['theme'] !== 'tutorial') { + $theme = $this->ymlString($config['theme']); + $themeYML = <<writeToFile("mysite/_config/theme.yml", <<getBaseDir(); $this->statusMessage("Setting up $base$filename"); if ((@$fh = fopen($base . $filename, 'wb')) && fwrite($fh, $content) && fclose($fh)) { + // Set permissions to writable + @chmod($base . $filename, 0775); return true; } $this->error("Couldn't write to file $base$filename"); return false; } + /** + * Ensure root .htaccess is setup + */ public function createHtaccess() { $start = "### SILVERSTRIPE START ###\n"; @@ -473,18 +559,6 @@ TEXT; HTML; } - public function var_export_array_nokeys($array) - { - $retval = "array(\n"; - foreach ($array as $item) { - $retval .= "\t'"; - $retval .= trim($item); - $retval .= "',\n"; - } - $retval .= ")"; - return $retval; - } - /** * Show an installation status message. * The output differs depending on whether this is CLI or web based @@ -496,4 +570,29 @@ HTML; echo "
  • $msg
  • \n"; flush(); } + + /** + * @param $config + */ + protected function sendInstallStats($config) + { + // Try to determine the database version from the helper + $dbType = $config['db']['type']; + $helper = $this->getDatabaseConfigurationHelper($dbType); + if ($helper) { + $databaseVersion = $dbType . ': ' . $helper->getDatabaseVersion($config['db']); + } else { + $databaseVersion = $dbType; + } + + $args = http_build_query(array_filter([ + 'SilverStripe' => $config['version'], + 'PHP' => phpversion(), + 'Database' => $databaseVersion, + 'WebServer' => $this->findWebserver(), + 'ID' => empty($_SESSION['StatsID']) ? null : $_SESSION['StatsID'] + ])); + $url = "http://ss2stat.silverstripe.com/Installation/add?{$args}"; + @$_SESSION['StatsID'] = file_get_contents($url); + } } diff --git a/src/Dev/Install/client/js/install.js b/src/Dev/Install/client/js/install.js index 2bd164d0e..40047180c 100644 --- a/src/Dev/Install/client/js/install.js +++ b/src/Dev/Install/client/js/install.js @@ -1,59 +1,49 @@ $(document).ready(function () { - /** - * Toggle field readonly modes, if check configuration comes from - * environment variables (values populated on reload). - */ - $('#use_environment').click(function (e) { - if (!$(this).is(':checked')) { - $('.configured-by-env').removeAttr('disabled'); - } else { - $('.configured-by-env').attr('disabled', 'disabled'); - } - }); + /** + * Hide all existing database warnings, and show only current one + */ + $('#database_selection > li > label, #database_selection > li > input:radio').click(function () { + $('.dbfields').hide(); + // only show fields if there's no db error + if (!$('.databaseError', $(this).parent()).length) { + $('.dbfields', $(this).parent()).show(); + } + $('.databaseError').hide(); + $('.databaseError', $(this).parent()).show(); + }); - /** - * Hide all existing database warnings, and show only current one - */ - $('#database_selection li label, #database_selection input:radio').click(function (e) { - $('.dbfields').hide(); - // only show fields if there's no db error - if (!$('.databaseError', $(this).parent()).length) { - $('.dbfields', $(this).parent()).show(); - } - $('.databaseError').hide(); - $('.databaseError', $(this).parent()).show(); - }); + // Handle install button + $('#install_button').click(function (e) { + // Confirm on re-install + if ( + $(this).hasClass('mustconfirm') + && !confirm('Are you sure you wish to replace the existing installation config?') + ) { + e.preventDefault(); + return false; + } - // Select first - $('#database_selection li input:checked').siblings('label').click(); + // Process + $('#saving_top').hide(); + $(this).val('Installing SilverStripe...'); + return true; + }); - /** - * Install button - */ - $('#reinstall_confirmation').click(function () { - $('#install_button').attr('disabled', !$(this).is(':checked')); - }); + /** + * Show all the requirements + */ + $('h5.requirement a').click(function () { + if ($(this).text() === 'Hide All Requirements') { + // hide the shown requirements + $(this).parents('h5').next('table.testResults').find('.good').hide(); + $(this).text('Show All Requirements'); + } else { + // show the requirements. + $(this).parents('h5').next('table.testResults').find('.good').show(); + $(this).text('Hide All Requirements'); + } - $('#install_button').click(function () { - $('#saving_top').hide(); - $(this).val('Installing SilverStripe...'); - }); - - /** - * Show all the requirements - */ - $('h5.requirement a').click(function () { - if ($(this).text() == 'Hide All Requirements') { - // hide the shown requirements - $(this).parents('h5').next('table.testResults').find('.good').hide(); - $(this).text('Show All Requirements'); - } else { - // show the requirements. - $(this).parents('h5').next('table.testResults').find('.good').show(); - $(this).text('Hide All Requirements'); - } - - return false; - }); + return false; + }); }); diff --git a/src/Dev/Install/config-form.html b/src/Dev/Install/config-form.html index a9685e3a3..6d2851210 100644 --- a/src/Dev/Install/config-form.html +++ b/src/Dev/Install/config-form.html @@ -7,8 +7,8 @@ SilverStripe CMS / Framework Installation - - + + @@ -41,7 +41,7 @@

    Note: SilverStripe is already installed here.
    - If you wish to reinstall SilverStripe, please delete the mysite/_config.php file first.

    + If you choose to reinstall SilverStripe, your current settings will be replaced

    hasWarnings()): ?>
    @@ -94,33 +94,24 @@
      $details) { - $checked = ($databaseConfig['type'] == $class || $type == $class) ? ' checked="checked"' : ''; + foreach ($databaseClasses as $class => $details) { + $checked = ($databaseConfig['type'] == $class) ? ' checked="checked"' : ''; $disabled = $help = ''; - if($usingEnv) { - // All are disabled by default when environment is used - $disabled = 'disabled="disabled"'; - // If SS_DATABASE_CLASS is specified, check the database in the list - if(getenv('SS_DATABASE_CLASS') == $class) { - $checked = ' checked="checked"'; - } - } else { - $disabled = !$details['supported'] || !$details['hasModule'] ? 'notavailable="true"' : ''; - if ($disabled) { - if (!$details['supported'] && !$details['hasModule']) { - $help = 'PHP does not have the required extension, and SilverStripe does not have the correct module installed'; - $helpText = '
    • '.$details['missingExtensionText'].'
    • '; - $helpText .= '
    • '.$details['missingModuleText'].'
    • '; - } else if ($details['supported'] && !$details['hasModule']) { - $help = 'PHP has the required extension, but SilverStripe is missing the module'; - $helpText = '
    • '.$details['missingModuleText'].'
    • '; - } else if (!$details['supported'] && $details['hasModule']) { - $help = 'SilverStripe has the module installed, but PHP is missing the required extension'; - $helpText = '
    • '.$details['missingExtensionText'].'
    • '; - } - $help .= "
        $helpText
      "; - } - } + $disabled = !$details['supported'] || !$details['hasModule'] ? 'notavailable="true"' : ''; + if ($disabled) { + if (!$details['supported'] && !$details['hasModule']) { + $help = 'PHP does not have the required extension, and SilverStripe does not have the correct module installed'; + $helpText = '
    • '.$details['missingExtensionText'].'
    • '; + $helpText .= '
    • '.$details['missingModuleText'].'
    • '; + } else if ($details['supported'] && !$details['hasModule']) { + $help = 'PHP has the required extension, but SilverStripe is missing the module'; + $helpText = '
    • '.$details['missingModuleText'].'
    • '; + } else if (!$details['supported'] && $details['hasModule']) { + $help = 'SilverStripe has the module installed, but PHP is missing the required extension'; + $helpText = '
    • '.$details['missingExtensionText'].'
    • '; + } + $help .= "
        $helpText
      "; + } echo "
    • "; echo ""; echo ""; @@ -129,7 +120,7 @@ } // generate db-specific config fields - echo '
      '; + echo $checked ? '
      ' : ' @@ -226,9 +211,8 @@ checked="checked">
    • -
    • checked="checked">
    • + checked="checked"> +
    • checked="checked">

    Confirm Install Step 5 of 5

    @@ -266,14 +250,14 @@

    - +

    diff --git a/src/Dev/Install/install.php b/src/Dev/Install/install.php index 69304eab5..65036954b 100644 --- a/src/Dev/Install/install.php +++ b/src/Dev/Install/install.php @@ -10,15 +10,13 @@ ************************************************************************************/ /** - * PHP version check. Make sure we've got at least PHP 5.5.0 in the most friendly way possible + * PHP version check. Make sure we've got at least PHP 5.6.0 in the most friendly way possible */ -define('FRAMEWORK_NAME', 'framework'); - -if (version_compare(phpversion(), '5.5.0', '<')) { +if (version_compare(phpversion(), '5.6.0', '<')) { header($_SERVER['SERVER_PROTOCOL'] . " 500 Server Error"); echo str_replace( - array('$PHPVersion', 'sapphire'), - array(phpversion(), FRAMEWORK_NAME), + '$PHPVersion', + phpversion(), file_get_contents(__DIR__ . "/php5-required.html") ); die(); diff --git a/src/Dev/Install/install5.php b/src/Dev/Install/install5.php index ebcfb7528..49479b9e2 100755 --- a/src/Dev/Install/install5.php +++ b/src/Dev/Install/install5.php @@ -37,70 +37,12 @@ if (function_exists('session_start') && !session_id()) { } // require composers autoloader -require __DIR__ . '/../../includes/autoload.php'; +require_once __DIR__ . '/../../includes/autoload.php'; -$usingEnv = !empty($_REQUEST['useEnv']); +$usingEnv = empty($_POST) || !empty($_REQUEST['useEnv']); // Set default locale, but try and sniff from the user agent -$defaultLocale = 'en_US'; -$locales = array( - 'af_ZA' => 'Afrikaans (South Africa)', - 'ar_EG' => 'Arabic (Egypt)', - 'hy_AM' => 'Armenian (Armenia)', - 'ast_ES' => 'Asturian (Spain)', - 'az_AZ' => 'Azerbaijani (Azerbaijan)', - 'bs_BA' => 'Bosnian (Bosnia and Herzegovina)', - 'bg_BG' => 'Bulgarian (Bulgaria)', - 'ca_ES' => 'Catalan (Spain)', - 'zh_CN' => 'Chinese (China)', - 'zh_TW' => 'Chinese (Taiwan)', - 'hr_HR' => 'Croatian (Croatia)', - 'cs_CZ' => 'Czech (Czech Republic)', - 'da_DK' => 'Danish (Denmark)', - 'nl_NL' => 'Dutch (Netherlands)', - 'en_GB' => 'English (United Kingdom)', - 'en_US' => 'English (United States)', - 'eo_XX' => 'Esperanto', - 'et_EE' => 'Estonian (Estonia)', - 'fo_FO' => 'Faroese (Faroe Islands)', - 'fi_FI' => 'Finnish (Finland)', - 'fr_FR' => 'French (France)', - 'de_DE' => 'German (Germany)', - 'el_GR' => 'Greek (Greece)', - 'he_IL' => 'Hebrew (Israel)', - 'hu_HU' => 'Hungarian (Hungary)', - 'is_IS' => 'Icelandic (Iceland)', - 'id_ID' => 'Indonesian (Indonesia)', - 'it_IT' => 'Italian (Italy)', - 'ja_JP' => 'Japanese (Japan)', - 'km_KH' => 'Khmer (Cambodia)', - 'lc_XX' => 'LOLCAT', - 'lv_LV' => 'Latvian (Latvia)', - 'lt_LT' => 'Lithuanian (Lithuania)', - 'ms_MY' => 'Malay (Malaysia)', - 'mi_NZ' => 'Maori (New Zealand)', - 'ne_NP' => 'Nepali (Nepal)', - 'nb_NO' => 'Norwegian', - 'fa_IR' => 'Persian (Iran)', - 'pl_PL' => 'Polish (Poland)', - 'pt_BR' => 'Portuguese (Brazil)', - 'pa_IN' => 'Punjabi (India)', - 'ro_RO' => 'Romanian (Romania)', - 'ru_RU' => 'Russian (Russia)', - 'sr_RS' => 'Serbian (Serbia)', - 'si_LK' => 'Sinhalese (Sri Lanka)', - 'sk_SK' => 'Slovak (Slovakia)', - 'sl_SI' => 'Slovenian (Slovenia)', - 'es_AR' => 'Spanish (Argentina)', - 'es_MX' => 'Spanish (Mexico)', - 'es_ES' => 'Spanish (Spain)', - 'sv_SE' => 'Swedish (Sweden)', - 'th_TH' => 'Thai (Thailand)', - 'tr_TR' => 'Turkish (Turkey)', - 'uk_UA' => 'Ukrainian (Ukraine)', - 'uz_UZ' => 'Uzbek (Uzbekistan)', - 'vi_VN' => 'Vietnamese (Vietnam)', -); +$locale = isset($_POST['locale']) ? $_POST['locale'] : 'en_US'; // Discover which databases are available DatabaseAdapterRegistry::autodiscover(); @@ -112,112 +54,18 @@ foreach ($databaseClasses as $class => $details) { $databaseClasses[$class]['hasModule'] = !empty($helper); } -// Load database config -/** @skipUpgrade */ -if (isset($_REQUEST['db'])) { - if (isset($_REQUEST['db']['type'])) { - $type = $_REQUEST['db']['type']; - } else { - if ($type = getenv('SS_DATABASE_CLASS')) { - $_REQUEST['db']['type'] = $type; - } elseif ($databaseClasses['MySQLPDODatabase']['supported']) { - $type = $_REQUEST['db']['type'] = 'MySQLPDODatabase'; - } elseif ($databaseClasses['MySQLDatabase']['supported']) { - $type = $_REQUEST['db']['type'] = 'MySQLDatabase'; - } else { - // handle error - } - } - - // Disabled inputs don't submit anything - we need to use the environment (except the database name) - if ($usingEnv) { - $_REQUEST['db'][$type] = $databaseConfig = array( - "type" => getenv('SS_DATABASE_CLASS') ?: $type, - "server" => getenv('SS_DATABASE_SERVER') ?: "localhost", - "username" => getenv('SS_DATABASE_USERNAME') ?: "root", - "password" => getenv('SS_DATABASE_PASSWORD') ?: "", - "database" => $_REQUEST['db'][$type]['database'], - ); - - // Set SSL parameters if they exist - if (getenv('SS_DATABASE_SSL_KEY') && getenv('SS_DATABASE_SSL_CERT')) { - $databaseConfig['ssl_key'] = getenv('SS_DATABASE_SSL_KEY'); - $databaseConfig['ssl_cert'] = getenv('SS_DATABASE_SSL_CERT'); - } - if (getenv('SS_DATABASE_SSL_CA')) { - $databaseConfig['ssl_ca'] = getenv('SS_DATABASE_SSL_CA'); - } - if (getenv('SS_DATABASE_SSL_CIPHER')) { - $databaseConfig['ssl_ca'] = getenv('SS_DATABASE_SSL_CIPHER'); - } - } else { - // Normal behaviour without the environment - $databaseConfig = $_REQUEST['db'][$type]; - $databaseConfig['type'] = $type; - } -} else { - if ($type = getenv('SS_DATABASE_CLASS')) { - $_REQUEST['db']['type'] = $type; - } elseif ($databaseClasses['MySQLPDODatabase']['supported']) { - $type = $_REQUEST['db']['type'] = 'MySQLPDODatabase'; - } elseif ($databaseClasses['MySQLDatabase']['supported']) { - $type = $_REQUEST['db']['type'] = 'MySQLDatabase'; - } else { - // handle error - } - $_REQUEST['db'][$type] = $databaseConfig = array( - "type" => $type, - "server" => getenv('SS_DATABASE_SERVER') ?: "localhost", - "username" => getenv('SS_DATABASE_USERNAME') ?: "root", - "password" => getenv('SS_DATABASE_PASSWORD') ?: "", - "database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite", - ); -} - -if (isset($_REQUEST['admin'])) { - // Disabled inputs don't submit anything - we need to use the environment (except the database name) - if ($usingEnv) { - $_REQUEST['admin'] = $adminConfig = array( - 'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin', - 'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '', - ); - } else { - $adminConfig = $_REQUEST['admin']; - } -} else { - $_REQUEST['admin'] = $adminConfig = array( - 'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin', - 'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '', - ); -} - -$alreadyInstalled = false; -if (file_exists('mysite/_config.php')) { - // Find the $database variable in the relevant config file without having to execute the config file - if (preg_match("/\\\$database\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) { - eval($parts[0]); - if (!empty($database)) { - $alreadyInstalled = true; - } - // Assume that if $databaseConfig is defined in mysite/_config.php, then a non-environment-based installation has - // already gone ahead - } elseif (preg_match( - "/\\\$databaseConfig\s*=\s*[^\n\r]+[\n\r]/", - file_get_contents("mysite/_config.php"), - $parts - )) { - $alreadyInstalled = true; - } -} - -if (file_exists(FRAMEWORK_NAME . '/silverstripe_version')) { - $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version'); -} else { - $silverstripe_version = "unknown"; -} +// Build config from config / environment / request +$config = new InstallConfig(); +$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses); +$adminConfig = $config->getAdminConfig($_REQUEST); +$alreadyInstalled = $config->alreadyInstalled(); +$silverstripe_version = $config->getFrameworkVersion(); +$sendStats = $config->canSendStats($_REQUEST); +$locales = $config->getLocales(); +$theme = $config->getTheme($_REQUEST); // Check requirements -$req = new InstallRequirements($originalIni); +$req = new InstallRequirements(); $req->check(); if ($req->isIIS()) { @@ -256,10 +104,18 @@ if ($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) { exit(1); } +// Path to client resources +$clientPath = (FRAMEWORK_DIR ? FRAMEWORK_DIR . '/' : '') . 'src/Dev/Install/client'; + + // config-form.html vars (placeholder to prevent deletion) [ - $defaultLocale, + $theme, + $clientPath, + $adminConfig, + $usingEnv, $silverstripe_version, + $locale, $locales, $webserverConfigFile, $hasErrorOtherThanDatabase, @@ -267,28 +123,26 @@ if ($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) { $phpIniLocation ]; -if ((isset($_REQUEST['go']) || $installFromCli) +// If already installed, ensure the user clicked "reinstall" +$expectedArg = $alreadyInstalled ? 'reinstall' : 'go'; +if ((isset($_REQUEST[$expectedArg]) || $installFromCli) && !$req->hasErrors() && !$dbReq->hasErrors() && $adminConfig['username'] && $adminConfig['password'] ) { // Confirm before reinstalling - if (!$installFromCli && $alreadyInstalled) { - include(__DIR__ . '/config-form.html'); - } else { - $inst = new Installer(); - if ($_REQUEST) { - $inst->install($_REQUEST); - } else { - $inst->install(array( - 'db' => $databaseConfig, - 'admin' => $adminConfig, - )); - } - } - -// Show the config form + $inst = new Installer(); + $inst->install([ + 'usingEnv' => $usingEnv, + 'locale' => $locale, + 'theme' => $theme, + 'version' => $silverstripe_version, + 'db' => $databaseConfig, + 'admin' => $adminConfig, + 'stats' => $sendStats, + ]); + // Show the config form } else { include(__DIR__ . '/config-form.html'); } diff --git a/src/Dev/Install/php5-required.html b/src/Dev/Install/php5-required.html index d27996a93..fb18e8576 100644 --- a/src/Dev/Install/php5-required.html +++ b/src/Dev/Install/php5-required.html @@ -30,7 +30,7 @@
    diff --git a/src/ORM/DatabaseAdmin.php b/src/ORM/DatabaseAdmin.php index 4dbe77916..54a068827 100644 --- a/src/ORM/DatabaseAdmin.php +++ b/src/ORM/DatabaseAdmin.php @@ -223,7 +223,7 @@ class DatabaseAdmin extends Controller // Assumes database class is like "MySQLDatabase" or "MSSQLDatabase" (suffixed with "Database") $dbType = substr(get_class($conn), 0, -8); $dbVersion = $conn->getVersion(); - $databaseName = (method_exists($conn, 'currentDatabase')) ? $conn->getSelectedDatabase() : ""; + $databaseName = $conn->getSelectedDatabase(); if (Director::is_cli()) { echo sprintf("\n\nBuilding database %s using %s %s\n\n", $databaseName, $dbType, $dbVersion);