NEW: Remove web installer, move to separate package (#9231)

* Remove installer

* Remove exposed install files

* Replace Dev/Install classes still in use

* Update changelog

* FIX make the grid field actions consistent to what they look like on pages

Resolves https://github.com/silverstripe/silverstripe-admin/issues/904

* Docs changes
This commit is contained in:
Aaron Carlino 2019-09-11 13:10:25 +12:00 committed by Ingo Schommer
parent 75cd9dc944
commit da6582f593
20 changed files with 20 additions and 3540 deletions

View File

@ -67,8 +67,7 @@
},
"expose": [
"client/images",
"client/styles",
"src/Dev/Install/client"
"client/styles"
]
},
"autoload": {

View File

@ -12,7 +12,6 @@ the server to update templates, website logic, and perform upgrades or maintenan
* PHP extension for image manipulation: Either `gd` or `imagick`
* PHP extension for a database connector (e.g. `pdo` or `mysqli`)
Our web-based [PHP installer](installation/) can check requirements.
Use [phpinfo()](http://php.net/manual/en/function.phpinfo.php) to inspect your configuration.
## Database

View File

@ -40,8 +40,7 @@ The CMS login can be accessed at `/admin`.
## Guided Installation
If you are unsure on how this all works, or prefer to follow
an installer wizard, please jump on our [lessons](https://www.silverstripe.org/learn/lessons/v4/).
If you are unsure on how this all works, please jump on our [lessons](https://www.silverstripe.org/learn/lessons/v4/).
Webserver setup is covered in
[Lesson 4: Setting up a local dev environment](https://www.silverstripe.org/learn/lessons/v4/up-and-running-setting-up-a-local-silverstripe-dev-environment-1)

View File

@ -2,11 +2,29 @@
## Overview {#overview}
* [Installer UI has been removed](#installer-ui) and offered as a separate module.
* [Generic login form styling](#login-forms)
* Removed `use_gzip` option on `HtmlEditorField` which used to compress the rich text editor dependency.
No longer required since compression is performed as part of the CMS build automatically.
See (#832)(https://github.com/silverstripe/silverstripe-admin/issues/832)
## Installer UI has been removed
Until now, core releases of SilverStripe would put drop an `install.php` file in the
public root that, when accessed with a browser, would offer an installation
UI prompting the user for all the necessary configuration of your project
and environment, and validating it before performing the installation.
While this may be an important part of the onboarding experience for newcomers
to SilverStripe, it is an unnecessary artefact and potential security risk
for the vast majority of developers who install SilverStripe with composer
and their own environment files.
The installer UI will continue to live on under the name "installer-wizard" in a
[separate package](https://github.com/silverstripe/silverstripe-installer-wizard), which
can be added incrementally to core recipe installation, using `composer require silverstripe/installer-wizard`.
It is no longer a commercially supported module.
## Generic login form styling {#login-forms}
Login forms in SilverStripe are traditionally embedded in your page template.

View File

@ -1,278 +0,0 @@
<?php
namespace SilverStripe\Dev\Install;
use BadMethodCallException;
use SilverStripe\Core\Environment;
/**
* Provides environment settings from the current request + environment
*
* @skipUpgrade
*/
class InstallConfig
{
use InstallEnvironmentAware;
/**
* List of preferred DB classes in order
*
* @var array
*/
protected $preferredDatabases = [
'MySQLDatabase',
'MySQLPDODatabase',
];
public function __construct($basePath = null)
{
$this->initBaseDir($basePath);
}
/**
* Get database config from the current environment
*
* @param array $request Request object
* @param array $databaseClasses Supported database config
* @param bool $realPassword Set to true to get the real password. If false, any non-posted
* password will be redacted as '********'. Note: Posted passwords are considered disclosed and
* never redacted.
* @return array
*/
public function getDatabaseConfig($request, $databaseClasses, $realPassword = true)
{
// Get config from request
if (isset($request['db']['type'])) {
$type = $request['db']['type'];
if (isset($request['db'][$type])) {
$config = $request['db'][$type];
// The posted placeholder must be substituted with the real password
if (isset($config['password']) && $config['password'] === Installer::PASSWORD_PLACEHOLDER) {
$config['password'] = Environment::getEnv('SS_DATABASE_PASSWORD') ?: '';
}
return array_merge([ 'type' => $type ], $config);
}
}
// Guess database config
return [
'type' => $this->getDatabaseClass($databaseClasses),
'server' => Environment::getEnv('SS_DATABASE_SERVER') ?: 'localhost',
'username' => Environment::getEnv('SS_DATABASE_USERNAME') ?: 'root',
'password' => $realPassword
? (Environment::getEnv('SS_DATABASE_PASSWORD') ?: '')
: Installer::PASSWORD_PLACEHOLDER, // Avoid password disclosure
'database' => Environment::getEnv('SS_DATABASE_NAME') ?: 'SS_mysite',
'path' => Environment::getEnv('SS_DATABASE_PATH')
?: Environment::getEnv('SS_SQLITE_DATABASE_PATH') // sqlite compat
?: null,
'key' => Environment::getEnv('SS_DATABASE_KEY')
?: Environment::getEnv('SS_SQLITE_DATABASE_KEY') // sqlite compat
?: null,
];
}
/**
* Get admin config from the environment
*
* @param array $request
* @param bool $realPassword Set to true to get the real password. If false, any non-posted
* password will be redacted as '********'. Note: Posted passwords are considered disclosed and
* never redacted.
* @return array
*/
public function getAdminConfig($request, $realPassword = true)
{
if (isset($request['admin'])) {
$config = $request['admin'];
if (isset($config['password']) && $config['password'] === Installer::PASSWORD_PLACEHOLDER) {
$config['password'] = Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '';
}
return $request['admin'];
}
return [
'username' => Environment::getEnv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
'password' => $realPassword
? (Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '')
: Installer::PASSWORD_PLACEHOLDER, // Avoid password disclosure
];
}
/**
* 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 $this->getBaseDir() . $this->getProjectDir() . DIRECTORY_SEPARATOR . '_config.php';
}
/**
* @return string
*/
protected function getEnvPath()
{
return $this->getBaseDir() . '.env';
}
/**
* Database configs available for configuration
*
* @param array $databaseClasses
* @return string
*/
protected function getDatabaseClass($databaseClasses)
{
$envDatabase = Environment::getEnv('SS_DATABASE_CLASS');
if ($envDatabase) {
return $envDatabase;
}
// 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' => 'Māori (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';
}
}

View File

@ -1,231 +0,0 @@
<?php
namespace SilverStripe\Dev\Install;
use BadMethodCallException;
use SilverStripe\Core\Path;
/**
* For classes which are aware of install, project, and environment state.
*
* These should be basic getters / setters that infer from current state.
*/
trait InstallEnvironmentAware
{
/**
* Base path
* @var
*/
protected $baseDir;
/**
* Init base path, or guess if able
*
* @param string|null $basePath
*/
protected function initBaseDir($basePath)
{
if ($basePath) {
$this->setBaseDir($basePath);
} elseif (defined('BASE_PATH')) {
$this->setBaseDir(BASE_PATH);
} else {
throw new BadMethodCallException("No BASE_PATH defined");
}
}
/**
* @param string $base
* @return $this
*/
protected function setBaseDir($base)
{
$this->baseDir = $base;
return $this;
}
/**
* Get base path for this installation
*
* @return string
*/
public function getBaseDir()
{
return Path::normalise($this->baseDir) . DIRECTORY_SEPARATOR;
}
/**
* Get path to public directory
*
* @return string
*/
public function getPublicDir()
{
$base = $this->getBaseDir();
$public = Path::join($base, 'public') . DIRECTORY_SEPARATOR;
if (file_exists($public)) {
return $public;
}
return $base;
}
/**
* Check that a module exists
*
* @param string $dirname
* @return bool
*/
public function checkModuleExists($dirname)
{
// Mysite is base-only and doesn't need _config.php to be counted
if (in_array($dirname, ['mysite', 'app'])) {
return file_exists($this->getBaseDir() . $dirname);
}
$paths = [
"vendor/silverstripe/{$dirname}/",
"{$dirname}/",
];
foreach ($paths as $path) {
$checks = ['_config', '_config.php'];
foreach ($checks as $check) {
if (file_exists($this->getBaseDir() . $path . $check)) {
return true;
}
}
}
return false;
}
/**
* Get project dir name.
*
* @return string 'app', or 'mysite' (deprecated)
*/
protected function getProjectDir()
{
$base = $this->getBaseDir();
if (is_dir($base . 'mysite')) {
/** @deprecated 4.2.0:5.0.0 */
return 'mysite';
}
// Default
return 'app';
}
/**
* Get src dir name for project
*
* @return string
*/
protected function getProjectSrcDir()
{
$projectDir = $this->getProjectDir();
if ($projectDir === 'mysite') {
/** @deprecated 4.2.0:5.0.0 */
return $projectDir . DIRECTORY_SEPARATOR . 'code';
}
// Default
return $projectDir . DIRECTORY_SEPARATOR . 'src';
}
/**
* Check if the web server is IIS and version greater than the given version.
*
* @param int $fromVersion
* @return bool
*/
public function isIIS($fromVersion = 7)
{
$webserver = $this->findWebserver();
if (preg_match('#.*IIS/(?<version>[.\\d]+)$#', $webserver, $matches)) {
return version_compare($matches['version'], $fromVersion, '>=');
}
return false;
}
/**
* @return bool
*/
public function isApache()
{
return strpos($this->findWebserver(), 'Apache') !== false;
}
/**
* Find the webserver software running on the PHP host.
*
* @return string|false Server software or boolean FALSE
*/
public function findWebserver()
{
// Try finding from SERVER_SIGNATURE or SERVER_SOFTWARE
if (!empty($_SERVER['SERVER_SIGNATURE'])) {
$webserver = $_SERVER['SERVER_SIGNATURE'];
} elseif (!empty($_SERVER['SERVER_SOFTWARE'])) {
$webserver = $_SERVER['SERVER_SOFTWARE'];
} else {
return false;
}
return strip_tags(trim($webserver));
}
public function testApacheRewriteExists($moduleName = 'mod_rewrite')
{
if (function_exists('apache_get_modules') && in_array($moduleName, apache_get_modules())) {
return true;
}
if (isset($_SERVER['HTTP_MOD_REWRITE']) && $_SERVER['HTTP_MOD_REWRITE'] == 'On') {
return true;
}
if (isset($_SERVER['REDIRECT_HTTP_MOD_REWRITE']) && $_SERVER['REDIRECT_HTTP_MOD_REWRITE'] == 'On') {
return true;
}
return false;
}
public function testIISRewriteModuleExists($moduleName = 'IIS_UrlRewriteModule')
{
if (isset($_SERVER[$moduleName]) && $_SERVER[$moduleName]) {
return true;
} else {
return false;
}
}
/**
* Determines if the web server has any rewriting capability.
*
* @return bool
*/
public function hasRewritingCapability()
{
return ($this->testApacheRewriteExists() || $this->testIISRewriteModuleExists());
}
/**
* Get "nice" database name without "Database" suffix
*
* @param string $databaseClass
* @return string
*/
public function getDatabaseTypeNice($databaseClass)
{
return substr($databaseClass, 0, -8);
}
/**
* Get an instance of a helper class for the specific database.
*
* @param string $databaseClass e.g. MySQLDatabase or MSSQLDatabase
* @return DatabaseConfigurationHelper
*/
public function getDatabaseConfigurationHelper($databaseClass)
{
return DatabaseAdapterRegistry::getDatabaseConfigurationHelper($databaseClass);
}
}

View File

@ -1,1146 +0,0 @@
<?php
namespace SilverStripe\Dev\Install;
use BadMethodCallException;
use Exception;
use InvalidArgumentException;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SilverStripe\Core\Path;
use SilverStripe\Core\TempFolder;
use SplFileInfo;
/**
* This class checks requirements
* Each of the requireXXX functions takes an argument which gives a user description of the test.
* It's an array of 3 parts:
* $description[0] - The test catetgory
* $description[1] - The test title
* $description[2] - The test error to show, if it goes wrong
*/
class InstallRequirements
{
use InstallEnvironmentAware;
/**
* List of errors
*
* @var array
*/
protected $errors = [];
/**
* List of warnings
*
* @var array
*/
protected $warnings = [];
/**
* List of tests
*
* @var array
*/
protected $tests = [];
/**
* Backup of original ini settings
* @var array
*/
protected $originalIni = [];
public function __construct($basePath = null)
{
$this->initBaseDir($basePath);
}
/**
* Check the database configuration. These are done one after another
* starting with checking the database function exists in PHP, and
* continuing onto more difficult checks like database permissions.
*
* @param array $databaseConfig The list of database parameters
* @return boolean Validity of database configuration details
*/
public function checkDatabase($databaseConfig)
{
// Check if support is available
if (!$this->requireDatabaseFunctions(
$databaseConfig,
array(
"Database Configuration",
"Database support",
"Database support in PHP",
$this->getDatabaseTypeNice($databaseConfig['type'])
)
)
) {
return false;
}
$path = empty($databaseConfig['path']) ? null : $databaseConfig['path'];
$server = empty($databaseConfig['server']) ? null : $databaseConfig['server'];
// Check if the server is available
$usePath = $path && empty($server);
if (!$this->requireDatabaseServer(
$databaseConfig,
array(
"Database Configuration",
"Database server",
$usePath
? "I couldn't write to path '{$path}'"
: "I couldn't find a database server on '{$server}'",
$usePath
? $path
: $server
)
)
) {
return false;
}
// Check if the connection credentials allow access to the server / database
if (!$this->requireDatabaseConnection(
$databaseConfig,
array(
"Database Configuration",
"Database access credentials",
"That username/password doesn't work"
)
)
) {
return false;
}
// Check the necessary server version is available
if (!$this->requireDatabaseVersion(
$databaseConfig,
array(
"Database Configuration",
"Database server version requirement",
'',
'Version ' . $this->getDatabaseConfigurationHelper($databaseConfig['type'])->getDatabaseVersion($databaseConfig)
)
)
) {
return false;
}
// Check that database creation permissions are available
if (!$this->requireDatabaseOrCreatePermissions(
$databaseConfig,
array(
"Database Configuration",
"Can I access/create the database",
"I can't create new databases and the database '$databaseConfig[database]' doesn't exist"
)
)
) {
return false;
}
// Check alter permission (necessary to create tables etc)
if (!$this->requireDatabaseAlterPermissions(
$databaseConfig,
array(
"Database Configuration",
"Can I ALTER tables",
"I don't have permission to ALTER tables"
)
)
) {
return false;
}
// Success!
return true;
}
public function checkAdminConfig($adminConfig)
{
if (!$adminConfig['username']) {
$this->error(array('', 'Please enter a username!'));
}
if (!$adminConfig['password']) {
$this->error(array('', 'Please enter a password!'));
}
}
/**
* Check everything except the database
*
* @param array $originalIni
* @return array
*/
public function check($originalIni)
{
$this->originalIni = $originalIni;
$this->errors = [];
$isApache = $this->isApache();
$isIIS = $this->isIIS();
$webserver = $this->findWebserver();
// Get project dirs to inspect
$projectDir = $this->getProjectDir();
$projectSrcDir = $this->getProjectSrcDir();
$this->requirePHPVersion('5.5.0', '5.5.0', array(
"PHP Configuration",
"PHP5 installed",
null,
"PHP version " . phpversion()
));
// Check that we can identify the root folder successfully
$this->requireFile('vendor/silverstripe/framework/src/Dev/Install/config-form.html', array(
"File permissions",
"Does the webserver know where files are stored?",
"The webserver isn't letting me identify where files are stored.",
$this->getBaseDir()
));
$this->requireModule($projectDir, [
"File permissions",
"{$projectDir}/ directory exists?",
''
]);
$this->requireModule('vendor/silverstripe/framework', array(
"File permissions",
"vendor/silverstripe/framework/ directory exists?",
'',
));
$this->requireWriteable(
$this->getPublicDir() . 'index.php',
[
"File permissions",
"Is the index.php file writeable?",
null,
],
true
);
$this->requireWriteable('.env', ["File permissions", "Is the .env file writeable?", null], false, false);
if ($isApache) {
$this->checkApacheVersion(array(
"Webserver Configuration",
"Webserver is not Apache 1.x",
"SilverStripe requires Apache version 2 or greater",
$webserver
));
$this->requireWriteable(
$this->getPublicDir() . '.htaccess',
array("File permissions", "Is the .htaccess file writeable?", null),
true
);
} elseif ($isIIS) {
$this->requireWriteable(
$this->getPublicDir() . 'web.config',
array("File permissions", "Is the web.config file writeable?", null),
true
);
}
$this->requireWriteable("{$projectDir}/_config.php", [
"File permissions",
"Is the {$projectDir}/_config.php file writeable?",
null,
]);
$this->requireWriteable("{$projectDir}/_config/theme.yml", [
"File permissions",
"Is the {$projectDir}/_config/theme.yml file writeable?",
null,
]);
if (!$this->checkModuleExists('cms')) {
$this->requireWriteable("{$projectSrcDir}/RootURLController.php", [
"File permissions",
"Is the {$projectSrcDir}/RootURLController.php file writeable?",
null,
]);
}
// Check public folder exists
$this->requireFile(
'public',
[
'File permissions',
'Is there a public/ directory?',
'It is recommended to have a separate public/ web directory',
],
false,
false
);
// Ensure root assets dir is writable
$this->requireWriteable(
ASSETS_PATH,
array("File permissions", "Is the assets/ directory writeable?", null),
true
);
// Make sure asset path actually exists
if (!file_exists(ASSETS_PATH)) {
mkdir(ASSETS_PATH);
}
// Ensure all assets files are writable
$innerIterator = new RecursiveDirectoryIterator(ASSETS_PATH, RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new RecursiveIteratorIterator($innerIterator, RecursiveIteratorIterator::SELF_FIRST);
/** @var SplFileInfo $file */
foreach ($iterator as $file) {
// Only report file as error if not writable
if ($file->isWritable()) {
continue;
}
$relativePath = substr($file->getPathname(), strlen($this->getBaseDir()));
$message = $file->isDir()
? "Is the {$relativePath} directory writeable?"
: "Is the {$relativePath} file writeable?";
$this->requireWriteable($relativePath, array("File permissions", $message, null));
}
try {
$tempFolder = TempFolder::getTempFolder($this->getBaseDir());
} catch (Exception $e) {
$tempFolder = false;
}
$this->requireTempFolder(array('File permissions', 'Is a temporary directory available?', null, $tempFolder));
if ($tempFolder) {
// in addition to the temp folder being available, check it is writable
$this->requireWriteable($tempFolder, array(
"File permissions",
sprintf("Is the temporary directory writeable?", $tempFolder),
null
), true);
}
// Check for web server, unless we're calling the installer from the command-line
$this->isRunningWebServer(array("Webserver Configuration", "Server software", "Unknown", $webserver));
if ($isApache) {
$this->requireApacheRewriteModule('mod_rewrite', array(
"Webserver Configuration",
"URL rewriting support",
"You need mod_rewrite to use friendly URLs with SilverStripe, but it is not enabled."
));
} elseif ($isIIS) {
$this->requireIISRewriteModule('IIS_UrlRewriteModule', array(
"Webserver Configuration",
"URL rewriting support",
"You need to enable the IIS URL Rewrite Module to use friendly URLs with SilverStripe, "
. "but it is not installed or enabled. Download it for IIS 7 from http://www.iis.net/expand/URLRewrite"
));
} else {
$this->warning(array(
"Webserver Configuration",
"URL rewriting support",
"I can't tell whether any rewriting module is running. You may need to configure a rewriting rule yourself."
));
}
$this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
"Webserver Configuration",
"Recognised webserver",
"You seem to be using an unsupported webserver. "
. "The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."
));
$this->requirePostSupport(array(
"Webserver Configuration",
"POST Support",
'I can\'t find $_POST, make sure POST is enabled.'
));
// Check for GD support
if (!$this->requireFunction("imagecreatetruecolor", array(
"PHP Configuration",
"GD2 support",
"PHP must have GD version 2."
))
) {
$this->requireFunction("imagecreate", array(
"PHP Configuration",
"GD2 support",
"GD support for PHP not included."
));
}
// Check for XML support
$this->requireFunction('xml_set_object', array(
"PHP Configuration",
"XML support",
"XML support not included in PHP."
));
$this->requireClass('DOMDocument', array(
"PHP Configuration",
"DOM/XML support",
"DOM/XML support not included in PHP."
));
$this->requireFunction('simplexml_load_file', array(
'PHP Configuration',
'SimpleXML support',
'SimpleXML support not included in PHP.'
));
// Check for INTL support
$this->requireClass('IntlTimeZone', array(
'PHP Configuration',
'Intl support',
'Internationalization (php-intl) support not included in PHP.'
));
// Check for token_get_all
$this->requireFunction('token_get_all', array(
"PHP Configuration",
"Tokenizer support",
"Tokenizer support not included in PHP."
));
// Check for CType support
$this->requireFunction('ctype_digit', array(
'PHP Configuration',
'CType support',
'CType support not included in PHP.'
));
// Check for session support
$this->requireFunction('session_start', array(
'PHP Configuration',
'Session support',
'Session support not included in PHP.'
));
// Check for iconv support
$this->requireFunction('iconv', array(
'PHP Configuration',
'iconv support',
'iconv support not included in PHP.'
));
// Check for hash support
$this->requireFunction('hash', array('PHP Configuration', 'hash support', 'hash support not included in PHP.'));
// Check for mbstring support
$this->requireFunction('mb_internal_encoding', array(
'PHP Configuration',
'mbstring support',
'mbstring support not included in PHP.'
));
// Check for Reflection support
$this->requireClass('ReflectionClass', array(
'PHP Configuration',
'Reflection support',
'Reflection support not included in PHP.'
));
// Check for Standard PHP Library (SPL) support
$this->requireFunction('spl_classes', array(
'PHP Configuration',
'SPL support',
'Standard PHP Library (SPL) not included in PHP.'
));
$this->requireDateTimezone(array(
'PHP Configuration',
'date.timezone setting and validity',
'date.timezone option in php.ini must be set correctly.',
$this->getOriginalIni('date.timezone')
));
$this->suggestClass('finfo', array(
'PHP Configuration',
'fileinfo support',
'fileinfo should be enabled in PHP. SilverStripe uses it for MIME type detection of files. '
. 'SilverStripe will still operate, but email attachments and sending files to browser '
. '(e.g. export data to CSV) may not work correctly without finfo.'
));
$this->suggestFunction('curl_init', array(
'PHP Configuration',
'curl support',
'curl should be enabled in PHP. SilverStripe uses it for consuming web services'
. ' via the RestfulService class and many modules rely on it.'
));
$this->suggestClass('tidy', array(
'PHP Configuration',
'tidy support',
'Tidy provides a library of code to clean up your html. '
. 'SilverStripe will operate fine without tidy but HTMLCleaner will not be effective.'
));
$this->suggestPHPSetting('asp_tags', array(false), array(
'PHP Configuration',
'asp_tags option',
'This should be turned off as it can cause issues with SilverStripe'
));
$this->requirePHPSetting('magic_quotes_gpc', array(false), array(
'PHP Configuration',
'magic_quotes_gpc option',
'This should be turned off, as it can cause issues with cookies. '
. 'More specifically, unserializing data stored in cookies.'
));
$this->suggestPHPSetting('display_errors', array(false), array(
'PHP Configuration',
'display_errors option',
'Unless you\'re in a development environment, this should be turned off, '
. 'as it can expose sensitive data to website users.'
));
// on some weirdly configured webservers arg_separator.output is set to &amp;
// which will results in links like ?param=value&amp;foo=bar which will not be i
$this->suggestPHPSetting('arg_separator.output', array('&', ''), array(
'PHP Configuration',
'arg_separator.output option',
'This option defines how URL parameters are concatenated. '
. 'If not set to \'&\' this may cause issues with URL GET parameters'
));
// always_populate_raw_post_data should be set to -1 if PHP < 7.0
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
$this->suggestPHPSetting('always_populate_raw_post_data', ['-1'], [
'PHP Configuration',
'always_populate_raw_post_data option',
'It\'s highly recommended to set this to \'-1\' in php 5.x, as $HTTP_RAW_POST_DATA is removed in php 7'
]);
}
// Check memory allocation
$this->requireMemory(32 * 1024 * 1024, 64 * 1024 * 1024, array(
"PHP Configuration",
"Memory allocation (PHP config option 'memory_limit')",
"SilverStripe needs a minimum of 32M allocated to PHP, but recommends 64M.",
$this->getOriginalIni("memory_limit")
));
return $this->errors;
}
/**
* Get ini setting
*
* @param string $settingName
* @return mixed
*/
protected function getOriginalIni($settingName)
{
if (isset($this->originalIni[$settingName])) {
return $this->originalIni[$settingName];
}
return ini_get($settingName);
}
public function suggestPHPSetting($settingName, $settingValues, $testDetails)
{
$this->testing($testDetails);
// special case for display_errors, check the original value before
// it was changed at the start of this script.
$val = $this->getOriginalIni($settingName);
if (!in_array($val, $settingValues) && $val != $settingValues) {
$this->warning($testDetails, "$settingName is set to '$val' in php.ini. $testDetails[2]");
}
}
public function requirePHPSetting($settingName, $settingValues, $testDetails)
{
$this->testing($testDetails);
$val = $this->getOriginalIni($settingName);
if (!in_array($val, $settingValues) && $val != $settingValues) {
$this->error($testDetails, "$settingName is set to '$val' in php.ini. $testDetails[2]");
}
}
public function suggestClass($class, $testDetails)
{
$this->testing($testDetails);
if (!class_exists($class)) {
$this->warning($testDetails);
}
}
public function suggestFunction($class, $testDetails)
{
$this->testing($testDetails);
if (!function_exists($class)) {
$this->warning($testDetails);
}
}
public function requireDateTimezone($testDetails)
{
$this->testing($testDetails);
$val = $this->getOriginalIni('date.timezone');
$result = $val && in_array($val, timezone_identifiers_list());
if (!$result) {
$this->error($testDetails);
}
}
public function requireMemory($min, $recommended, $testDetails)
{
$_SESSION['forcemem'] = false;
$mem = $this->getPHPMemory();
$memLimit = $this->getOriginalIni("memory_limit");
if ($mem < (64 * 1024 * 1024)) {
ini_set('memory_limit', '64M');
$mem = $this->getPHPMemory();
$testDetails[3] = $memLimit;
}
$this->testing($testDetails);
if ($mem < $min && $mem > 0) {
$message = $testDetails[2] . " You only have " . $memLimit . " allocated";
$this->error($testDetails, $message);
return false;
} elseif ($mem < $recommended && $mem > 0) {
$message = $testDetails[2] . " You only have " . $memLimit . " allocated";
$this->warning($testDetails, $message);
return false;
} elseif ($mem == 0) {
$message = $testDetails[2] . " We can't determine how much memory you have allocated. "
. "Install only if you're sure you've allocated at least 20 MB.";
$this->warning($testDetails, $message);
return false;
}
return true;
}
public function getPHPMemory()
{
$memString = $this->getOriginalIni("memory_limit");
switch (strtolower(substr($memString, -1))) {
case "k":
return round(substr($memString, 0, -1) * 1024);
case "m":
return round(substr($memString, 0, -1) * 1024 * 1024);
case "g":
return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
default:
return round($memString);
}
}
public function listErrors()
{
if ($this->errors) {
echo "<p>The following problems are preventing me from installing SilverStripe CMS:</p>\n\n";
foreach ($this->errors as $error) {
echo "<li>" . htmlentities(implode(", ", $error), ENT_COMPAT, 'UTF-8') . "</li>\n";
}
}
}
public function showTable($section = null)
{
if ($section) {
$tests = $this->tests[$section];
$id = strtolower(str_replace(' ', '_', $section));
echo "<table id=\"{$id}_results\" class=\"testResults\" width=\"100%\">";
foreach ($tests as $test => $result) {
echo "<tr class=\"$result[0]\"><td>$test</td><td>"
. nl2br(htmlentities($result[1], ENT_COMPAT, 'UTF-8')) . "</td></tr>";
}
echo "</table>";
} else {
foreach ($this->tests as $section => $tests) {
$failedRequirements = 0;
$warningRequirements = 0;
$output = "";
foreach ($tests as $test => $result) {
if (isset($result['0'])) {
switch ($result['0']) {
case 'error':
$failedRequirements++;
break;
case 'warning':
$warningRequirements++;
break;
}
}
$output .= "<tr class=\"$result[0]\"><td>$test</td><td>"
. nl2br(htmlentities($result[1], ENT_COMPAT, 'UTF-8')) . "</td></tr>";
}
$className = "good";
$text = "All Requirements Pass";
$pluralWarnings = ($warningRequirements == 1) ? 'Warning' : 'Warnings';
if ($failedRequirements > 0) {
$className = "error";
$pluralWarnings = ($warningRequirements == 1) ? 'Warning' : 'Warnings';
$text = $failedRequirements . ' Failed and ' . $warningRequirements . ' ' . $pluralWarnings;
} elseif ($warningRequirements > 0) {
$className = "warning";
$text = "All Requirements Pass but " . $warningRequirements . ' ' . $pluralWarnings;
}
echo "<h5 class='requirement $className'>$section <a href='#'>Show All Requirements</a> <span>$text</span></h5>";
echo "<table class=\"testResults\">";
echo $output;
echo "</table>";
}
}
}
public function requireFunction($funcName, $testDetails)
{
$this->testing($testDetails);
if (!function_exists($funcName)) {
$this->error($testDetails);
return false;
}
return true;
}
public function requireClass($className, $testDetails)
{
$this->testing($testDetails);
if (!class_exists($className)) {
$this->error($testDetails);
return false;
}
return true;
}
/**
* Require that the given class doesn't exist
*
* @param array $classNames
* @param array $testDetails
* @return bool
*/
public function requireNoClasses($classNames, $testDetails)
{
$this->testing($testDetails);
$badClasses = array();
foreach ($classNames as $className) {
if (class_exists($className)) {
$badClasses[] = $className;
}
}
if ($badClasses) {
$message = $testDetails[2] . ". The following classes are at fault: " . implode(', ', $badClasses);
$this->error($testDetails, $message);
return false;
}
return true;
}
public function checkApacheVersion($testDetails)
{
$this->testing($testDetails);
$is1pointx = preg_match('#Apache[/ ]1\.#', $testDetails[3]);
if ($is1pointx) {
$this->error($testDetails);
}
return true;
}
public function requirePHPVersion($recommendedVersion, $requiredVersion, $testDetails)
{
$this->testing($testDetails);
$installedVersion = phpversion();
if (version_compare($installedVersion, $requiredVersion, '<')) {
$message = "SilverStripe requires PHP version $requiredVersion or later.\n
PHP version $installedVersion is currently installed.\n
While SilverStripe requires at least PHP version $requiredVersion, upgrading to $recommendedVersion or later is recommended.\n
If you are installing SilverStripe on a shared web server, please ask your web hosting provider to upgrade PHP for you.";
$this->error($testDetails, $message);
return false;
}
if (version_compare($installedVersion, $recommendedVersion, '<')) {
$message = "PHP version $installedVersion is currently installed.\n
Upgrading to at least PHP version $recommendedVersion is recommended.\n
SilverStripe should run, but you may run into issues. Future releases may require a later version of PHP.\n";
$this->warning($testDetails, $message);
return false;
}
return true;
}
/**
* The same as {@link requireFile()} but does additional checks
* to ensure the module directory is intact.
*
* @param string $dirname
* @param array $testDetails
*/
public function requireModule($dirname, $testDetails)
{
$this->testing($testDetails);
$path = $this->getBaseDir() . $dirname;
if (!file_exists($path)) {
$testDetails[2] .= " Directory '$path' not found. Please make sure you have uploaded the SilverStripe files to your webserver correctly.";
$this->error($testDetails);
} elseif (!file_exists($path . '/_config.php') && !in_array($dirname, ['mysite', 'app'])) {
$testDetails[2] .= " Directory '$path' exists, but is missing files. Please make sure you have uploaded "
. "the SilverStripe files to your webserver correctly.";
$this->error($testDetails);
}
}
public function requireFile($filename, $testDetails, $absolute = false, $error = true)
{
$this->testing($testDetails);
if ($absolute) {
$filename = Path::normalise($filename);
} else {
$filename = Path::join($this->getBaseDir(), $filename);
}
if (file_exists($filename)) {
return;
}
$testDetails[2] .= " (file '$filename' not found)";
if ($error) {
$this->error($testDetails);
} else {
$this->warning($testDetails);
}
}
public function requireWriteable($filename, $testDetails, $absolute = false, $error = true)
{
$this->testing($testDetails);
if ($absolute) {
$filename = Path::normalise($filename);
} else {
$filename = Path::join($this->getBaseDir(), $filename);
}
if (file_exists($filename)) {
$isWriteable = is_writeable($filename);
} else {
$isWriteable = is_writeable(dirname($filename));
}
if ($isWriteable) {
return;
}
if (function_exists('posix_getgroups')) {
$userID = posix_geteuid();
$user = posix_getpwuid($userID);
$currentOwnerID = fileowner(file_exists($filename) ? $filename : dirname($filename));
$currentOwner = posix_getpwuid($currentOwnerID);
$testDetails[2] .= "User '$user[name]' needs to be able to write to this file:\n$filename\n\nThe "
. "file is currently owned by '$currentOwner[name]'. ";
if ($user['name'] == $currentOwner['name']) {
$testDetails[2] .= "We recommend that you make the file writeable.";
} else {
$groups = posix_getgroups();
$groupList = array();
foreach ($groups as $group) {
$groupInfo = posix_getgrgid($group);
if (in_array($currentOwner['name'], $groupInfo['members'])) {
$groupList[] = $groupInfo['name'];
}
}
if ($groupList) {
$testDetails[2] .= " We recommend that you make the file group-writeable "
. "and change the group to one of these groups:\n - " . implode("\n - ", $groupList)
. "\n\nFor example:\nchmod g+w $filename\nchgrp " . $groupList[0] . " $filename";
} else {
$testDetails[2] .= " There is no user-group that contains both the web-server user and the "
. "owner of this file. Change the ownership of the file, create a new group, or "
. "temporarily make the file writeable by everyone during the install process.";
}
}
} else {
$testDetails[2] .= "The webserver user needs to be able to write to this file:\n$filename";
}
if ($error) {
$this->error($testDetails);
} else {
$this->warning($testDetails);
}
}
public function requireTempFolder($testDetails)
{
$this->testing($testDetails);
try {
$tempFolder = TempFolder::getTempFolder($this->getBaseDir());
} catch (Exception $e) {
$tempFolder = false;
}
if (!$tempFolder) {
$testDetails[2] = "Permission problem gaining access to a temp directory. " .
"Please create a folder named silverstripe-cache in the base directory " .
"of the installation and ensure it has the adequate permissions.";
$this->error($testDetails);
}
}
public function requireApacheModule($moduleName, $testDetails)
{
$this->testing($testDetails);
if (!in_array($moduleName, apache_get_modules())) {
$this->error($testDetails);
return false;
} else {
return true;
}
}
public function requireApacheRewriteModule($moduleName, $testDetails)
{
$this->testing($testDetails);
if ($this->testApacheRewriteExists()) {
return true;
} else {
$this->error($testDetails);
return false;
}
}
public function requireIISRewriteModule($moduleName, $testDetails)
{
$this->testing($testDetails);
if ($this->testIISRewriteModuleExists()) {
return true;
} else {
$this->warning($testDetails);
return false;
}
}
public function requireDatabaseFunctions($databaseConfig, $testDetails)
{
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
if (!$helper) {
$this->error($testDetails, "Couldn't load database helper code for " . $databaseConfig['type']);
return false;
}
$result = $helper->requireDatabaseFunctions($databaseConfig);
if ($result) {
return true;
} else {
$this->error($testDetails);
return false;
}
}
public function requireDatabaseConnection($databaseConfig, $testDetails)
{
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseConnection($databaseConfig);
if ($result['success']) {
return true;
} else {
$testDetails[2] .= ": " . $result['error'];
$this->error($testDetails);
return false;
}
}
public function requireDatabaseVersion($databaseConfig, $testDetails)
{
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
if (method_exists($helper, 'requireDatabaseVersion')) {
$result = $helper->requireDatabaseVersion($databaseConfig);
if ($result['success']) {
return true;
} else {
$testDetails[2] .= $result['error'];
$this->warning($testDetails);
return false;
}
}
// Skipped test because this database has no required version
return true;
}
public function requireDatabaseServer($databaseConfig, $testDetails)
{
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseServer($databaseConfig);
if ($result['success']) {
return true;
} else {
$message = $testDetails[2] . ": " . $result['error'];
$this->error($testDetails, $message);
return false;
}
}
public function requireDatabaseOrCreatePermissions($databaseConfig, $testDetails)
{
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseOrCreatePermissions($databaseConfig);
if ($result['success']) {
if ($result['alreadyExists']) {
$testDetails[3] = "Database $databaseConfig[database]";
} else {
$testDetails[3] = "Able to create a new database";
}
$this->testing($testDetails);
return true;
} else {
if (empty($result['cannotCreate'])) {
$message = $testDetails[2] . ". Please create the database manually.";
} else {
$message = $testDetails[2] . " (user '$databaseConfig[username]' doesn't have CREATE DATABASE permissions.)";
}
$this->error($testDetails, $message);
return false;
}
}
public function requireDatabaseAlterPermissions($databaseConfig, $testDetails)
{
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseAlterPermissions($databaseConfig);
if ($result['success']) {
return true;
} else {
$message = "Silverstripe cannot alter tables. This won't prevent installation, however it may "
. "cause issues if you try to run a /dev/build once installed.";
$this->warning($testDetails, $message);
return false;
}
}
public function requireServerVariables($varNames, $testDetails)
{
$this->testing($testDetails);
$missing = array();
foreach ($varNames as $varName) {
if (!isset($_SERVER[$varName]) || !$_SERVER[$varName]) {
$missing[] = '$_SERVER[' . $varName . ']';
}
}
if (!$missing) {
return true;
}
$message = $testDetails[2] . " (the following PHP variables are missing: " . implode(", ", $missing) . ")";
$this->error($testDetails, $message);
return false;
}
public function requirePostSupport($testDetails)
{
$this->testing($testDetails);
if (!isset($_POST)) {
$this->error($testDetails);
return false;
}
return true;
}
public function isRunningWebServer($testDetails)
{
$this->testing($testDetails);
if ($testDetails[3]) {
return true;
} else {
$this->warning($testDetails);
return false;
}
}
public function testing($testDetails)
{
if (!$testDetails) {
return;
}
$section = $testDetails[0];
$test = $testDetails[1];
$message = "OK";
if (isset($testDetails[3])) {
$message .= " ($testDetails[3])";
}
$this->tests[$section][$test] = array("good", $message);
}
public function error($testDetails, $message = null)
{
if (!is_array($testDetails)) {
throw new InvalidArgumentException("Invalid error");
}
$section = $testDetails[0];
$test = $testDetails[1];
if (!$message && isset($testDetails[2])) {
$message = $testDetails[2];
}
$this->tests[$section][$test] = array("error", $message);
$this->errors[] = $testDetails;
}
public function warning($testDetails, $message = null)
{
if (!is_array($testDetails)) {
throw new InvalidArgumentException("Invalid warning");
}
$section = $testDetails[0];
$test = $testDetails[1];
if (!$message && isset($testDetails[2])) {
$message = $testDetails[2];
}
$this->tests[$section][$test] = array("warning", $message);
$this->warnings[] = $testDetails;
}
public function hasErrors()
{
return sizeof($this->errors);
}
public function hasWarnings()
{
return sizeof($this->warnings);
}
}

View File

@ -1,687 +0,0 @@
<?php
namespace SilverStripe\Dev\Install;
use Exception;
use SilverStripe\Control\Cookie;
use SilverStripe\Control\HTTPApplication;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPRequestBuilder;
use SilverStripe\Core\Convert;
use SilverStripe\Core\CoreKernel;
use SilverStripe\Core\EnvironmentLoader;
use SilverStripe\Core\Kernel;
use SilverStripe\Core\Path;
use SilverStripe\ORM\DatabaseAdmin;
use SilverStripe\Security\DefaultAdminService;
use SilverStripe\Security\Security;
use SilverStripe\Control\Middleware\URLSpecialsMiddleware\SessionEnvTypeSwitcher;
/**
* This installer doesn't use any of the fancy SilverStripe stuff in case it's unsupported.
*/
class Installer
{
use InstallEnvironmentAware;
use SessionEnvTypeSwitcher;
/**
* Errors during install
*
* @var array
*/
protected $errors = [];
/**
* value='' attribute placeholder for password fields
*/
const PASSWORD_PLACEHOLDER = '********';
public function __construct($basePath = null)
{
$this->initBaseDir($basePath);
}
/**
* Installer error
*
* @param string $message
*/
protected function error($message = null)
{
$this->errors[] = $message;
}
protected function installHeader()
{
$clientPath = RESOURCES_DIR . (PUBLIC_DIR
? '/vendor/silverstripe/framework/src/Dev/Install/client'
: '/silverstripe/framework/src/Dev/Install/client');
?>
<html>
<head>
<meta charset="utf-8"/>
<title>Installing SilverStripe...</title>
<link rel="stylesheet" type="text/css" href="<?=$clientPath; ?>/styles/install.css"/>
<script src="//code.jquery.com/jquery-1.7.2.min.js"></script>
</head>
<body>
<div class="install-header">
<div class="inner">
<div class="brand">
<h1>SilverStripe</h1>
</div>
</div>
</div>
<div id="Navigation">&nbsp;</div>
<div class="clear"><!-- --></div>
<div class="main">
<div class="inner">
<h2>Installing SilverStripe...</h2>
<p>I am now running through the installation steps (this should take about 30 seconds)</p>
<p>If you receive a fatal error, refresh this page to continue the installation</p>
<ul>
<?php
}
public function install($config)
{
// Render header
$this->installHeader();
$isIIS = $this->isIIS();
$isApache = $this->isApache();
$projectDir = $this->getProjectDir();
$projectSrcDir = $this->getProjectSrcDir();
flush();
// Send install stats
if (!empty($config['stats'])) {
$this->sendInstallStats($config);
}
// Cleanup _config.php
$basePath = $this->getBaseDir();
$appConfigPath = $basePath . "{$projectDir}/_config.php";
if (file_exists($appConfigPath)) {
// 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
$fh = fopen($appConfigPath, 'wb');
fclose($fh);
}
// Write all files
$this->writeIndexPHP();
$this->writeConfigPHP($config);
$this->writeConfigYaml($config);
$this->writeConfigEnv($config);
// Write other stuff
if (!$this->checkModuleExists('cms')) {
$rootURLControllerPath = $basePath . "{$projectSrcDir}/RootURLController.php";
$this->writeToFile($rootURLControllerPath, <<<PHP
<?php
use SilverStripe\\Control\\Controller;
class RootURLController extends Controller
{
public function index()
{
echo "<html>Your site is now set up. Start adding controllers to app/src to get started.</html>";
}
}
PHP
);
}
// Write the appropriate web server configuration file for rewriting support
if ($this->hasRewritingCapability()) {
if ($isApache) {
$this->createHtaccess();
} elseif ($isIIS) {
$this->createWebConfig();
}
}
// Build request
$request = HTTPRequestBuilder::createFromEnvironment();
// Install kernel (fix to dev)
$kernel = new CoreKernel(Path::normalise($basePath));
$kernel->setEnvironment(Kernel::DEV);
$app = new HTTPApplication($kernel);
// Build db within HTTPApplication
$app->execute($request, function (HTTPRequest $request) use ($config) {
// Suppress cookie errors on install
Cookie::config()->set('report_errors', false);
// Start session and execute
$request->getSession()->init($request);
// Output status
$this->statusMessage("Building database schema...");
// Setup DB
$dbAdmin = new DatabaseAdmin();
$dbAdmin->setRequest($request);
$dbAdmin->pushCurrent();
$dbAdmin->doInit();
$dbAdmin->doBuild(true);
// Create default administrator user and group in database
// (not using Security::setDefaultAdmin())
$username = $config['admin']['username'];
$password = $config['admin']['password'];
$adminMember = DefaultAdminService::singleton()
->findOrCreateAdmin(
$username,
_t('SilverStripe\\Security\\DefaultAdminService.DefaultAdminFirstname', 'Default Admin')
);
$adminMember->Email = $username;
$adminMember->Password = $password;
$adminMember->PasswordEncryption = Security::config()->get('encryption_algorithm');
try {
$this->statusMessage('Creating default CMS admin account...');
$adminMember->write();
} catch (Exception $e) {
$this->statusMessage(
sprintf('Warning: Default CMS admin account could not be created (error: %s)', $e->getMessage())
);
}
$request->getSession()->set('username', $username);
$request->getSession()->set('password', $password);
$request->getSession()->save($request);
}, true);
// Check result of install
if (!$this->errors) {
// switch the session to Dev mode so that
// flush does not require authentication
// for the first time after installation
$request['isDev'] = '1';
$this->setSessionEnvType($request);
unset($request['isDev']);
$request->getSession()->save($request);
if (isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) {
$this->statusMessage("Checking that friendly URLs work...");
$this->checkRewrite();
} else {
$params = http_build_query($request->getVars() + ['flush' => '']);
$destinationURL = 'index.php/' .
($this->checkModuleExists('cms') ? "home/successfullyinstalled?$params" : "?$params");
echo <<<HTML
<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li>
<script>
setTimeout(function() {
window.location = "$destinationURL";
}, 2000);
</script>
<noscript>
<li><a href="$destinationURL">Click here to access your site.</a></li>
</noscript>
HTML;
}
} else {
// Output all errors
$this->statusMessage('Encountered ' . count($this->errors) . ' errors during install:');
echo "<ul>";
foreach ($this->errors as $error) {
$this->statusMessage($error);
}
echo "</ul>";
$this->statusMessage('Please <a href="install.php">Click here</a> to return to the installer.');
}
return $this->errors;
}
protected function writeIndexPHP()
{
$content = <<<'PHP'
<?php
use SilverStripe\Control\HTTPApplication;
use SilverStripe\Control\HTTPRequestBuilder;
use SilverStripe\Core\CoreKernel;
// Find autoload.php
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
require __DIR__ . '/vendor/autoload.php';
} elseif (file_exists(__DIR__ . '/../vendor/autoload.php')) {
require __DIR__ . '/../vendor/autoload.php';
} else {
echo "autoload.php not found";
die;
}
// Build request and detect flush
$request = HTTPRequestBuilder::createFromEnvironment();
// Default application
$kernel = new CoreKernel(BASE_PATH);
$app = new HTTPApplication($kernel);
$response = $app->handle($request);
$response->output();
PHP;
$path = $this->getPublicDir() . 'index.php';
$this->writeToFile($path, $content, true);
}
/**
* Write all .env files
*
* @param $config
*/
protected function writeConfigEnv($config)
{
if (!$config['usingEnv']) {
return;
}
$path = $this->getBaseDir() . '.env';
$vars = [];
// Retain existing vars
$env = new EnvironmentLoader();
if (file_exists($path)) {
$vars = $env->loadFile($path) ?: [];
}
// 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
$env->loadFile($path);
}
/**
* Write all *.php files
*
* @param array $config
*/
protected function writeConfigPHP($config)
{
$configPath = $this->getProjectDir() . DIRECTORY_SEPARATOR . "_config.php";
if ($config['usingEnv']) {
$this->writeToFile($configPath, "<?php\n ");
return;
}
// Create databaseConfig
$lines = [];
foreach ($config['db'] as $key => $value) {
$lines[] = sprintf(
" '%s' => '%s'",
addslashes($key),
addslashes($value)
);
}
$databaseConfigContent = implode(",\n", $lines);
$this->writeToFile($configPath, <<<PHP
<?php
use SilverStripe\\ORM\\DB;
DB::setConfig([
{$databaseConfigContent}
]);
PHP
);
}
/**
* Write yml files
*
* @param array $config
*/
protected function writeConfigYaml($config)
{
// Escape user input for safe insertion into PHP file
$locale = $this->ymlString($config['locale']);
$projectDir = $this->getProjectDir();
// Set either specified, or no theme
if ($config['theme'] && $config['theme'] !== 'tutorial') {
$theme = $this->ymlString($config['theme']);
$themeYML = <<<YML
- '\$public'
- '$theme'
- '\$default'
YML;
} else {
$themeYML = <<<YML
- '\$public'
- '\$default'
YML;
}
// Write theme.yml
$this->writeToFile("{$projectDir}/_config/theme.yml", <<<YML
---
Name: mytheme
---
SilverStripe\\View\\SSViewer:
themes:
$themeYML
SilverStripe\\i18n\\i18n:
default_locale: '$locale'
YML
);
}
/**
* Escape yml string
*
* @param string $string
* @return mixed
*/
protected function ymlString($string)
{
// just escape single quotes using ''
return str_replace("'", "''", $string);
}
/**
* Write file to given location
*
* @param string $filename
* @param string $content
* @param bool $absolute If $filename is absolute path set to true
* @return bool
*/
public function writeToFile($filename, $content, $absolute = false)
{
// Get absolute / relative paths by either combining or removing base from path
list($absolutePath, $relativePath) = $absolute
? [
$filename,
substr($filename, strlen($this->getBaseDir()))]
: [
$this->getBaseDir() . $filename,
$filename
];
$this->statusMessage("Setting up $relativePath");
if ((@$fh = fopen($absolutePath, 'wb')) && fwrite($fh, $content) && fclose($fh)) {
// Set permissions to writable
@chmod($absolutePath, 0775);
return true;
}
$this->error("Couldn't write to file $relativePath");
return false;
}
/**
* Ensure root .htaccess is setup
*/
public function createHtaccess()
{
$start = "### SILVERSTRIPE START ###\n";
$end = "\n### SILVERSTRIPE END ###";
$base = dirname($_SERVER['SCRIPT_NAME']);
$base = Convert::slashes($base, '/');
if ($base != '.') {
$baseClause = "RewriteBase '$base'\n";
} else {
$baseClause = "";
}
if (strpos(strtolower(php_sapi_name()), "cgi") !== false) {
$cgiClause = "RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\n";
} else {
$cgiClause = "";
}
$rewrite = <<<TEXT
# Deny access to templates (but allow from localhost)
<Files *.ss>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Files>
# Deny access to IIS configuration
<Files web.config>
Order deny,allow
Deny from all
</Files>
# Deny access to YAML configuration files which might include sensitive information
<Files ~ "\.ya?ml$">
Order allow,deny
Deny from all
</Files>
# Route errors to static pages automatically generated by SilverStripe
ErrorDocument 404 /assets/error-404.html
ErrorDocument 500 /assets/error-500.html
<IfModule mod_rewrite.c>
# Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
<IfModule mod_dir.c>
DirectoryIndex disabled
DirectorySlash On
</IfModule>
SetEnv HTTP_MOD_REWRITE On
RewriteEngine On
$baseClause
$cgiClause
# Deny access to potentially sensitive files and folders
RewriteRule ^vendor(/|$) - [F,L,NC]
RewriteRule ^\.env - [F,L,NC]
RewriteRule silverstripe-cache(/|$) - [F,L,NC]
RewriteRule composer\.(json|lock) - [F,L,NC]
RewriteRule (error|silverstripe|debug)\.log - [F,L,NC]
# Process through SilverStripe if no file with the requested name exists.
# Pass through the original path as a query parameter, and retain the existing parameters.
# Try finding framework in the vendor folder first
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
</IfModule>
TEXT;
$htaccessPath = $this->getPublicDir() . '.htaccess';
if (file_exists($htaccessPath)) {
$htaccess = file_get_contents($htaccessPath);
if (strpos($htaccess, '### SILVERSTRIPE START ###') === false
&& strpos($htaccess, '### SILVERSTRIPE END ###') === false
) {
$htaccess .= "\n### SILVERSTRIPE START ###\n### SILVERSTRIPE END ###\n";
}
if (strpos($htaccess, '### SILVERSTRIPE START ###') !== false
&& strpos($htaccess, '### SILVERSTRIPE END ###') !== false
) {
$start = substr($htaccess, 0, strpos($htaccess, '### SILVERSTRIPE START ###'))
. "### SILVERSTRIPE START ###\n";
$end = "\n" . substr($htaccess, strpos($htaccess, '### SILVERSTRIPE END ###'));
}
}
$this->writeToFile($htaccessPath, $start . $rewrite . $end, true);
}
/**
* Writes basic configuration to the web.config for IIS
* so that rewriting capability can be use.
*/
public function createWebConfig()
{
$content = <<<TEXT
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments applyToWebDAV="false">
<add segment="silverstripe-cache" />
<add segment="composer.json" />
<add segment="composer.lock" />
</hiddenSegments>
<fileExtensions allowUnlisted="true" >
<add fileExtension=".ss" allowed="false"/>
<add fileExtension=".yml" allowed="false"/>
</fileExtensions>
</requestFiltering>
</security>
<rewrite>
<rules>
<rule name="SilverStripe Clean URLs" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
TEXT;
$path = $this->getPublicDir() . 'web.config';
$this->writeToFile($path, $content, true);
}
public function checkRewrite()
{
$params = http_build_query(['flush' => '']);
$destinationURL = rtrim(BASE_URL, '/') . '/' . (
$this->checkModuleExists('cms')
? "home/successfullyinstalled?$params"
: "?$params"
);
echo <<<HTML
<li id="ModRewriteResult">Testing...</li>
<script>
if (typeof $ == 'undefined') {
document.getElementById('ModeRewriteResult').innerHTML = "I can't run jQuery ajax to set rewriting; I will redirect you to the homepage to see if everything is working.";
setTimeout(function() {
window.location = "$destinationURL";
}, 10000);
} else {
$.ajax({
method: 'get',
url: 'InstallerTest/testrewrite',
complete: function(response) {
var r = response.responseText.replace(/[^A-Z]?/g,"");
if (r === "OK") {
$('#ModRewriteResult').html("Friendly URLs set up successfully; I am now redirecting you to your SilverStripe site...")
setTimeout(function() {
window.location = "$destinationURL";
}, 2000);
} else {
$('#ModRewriteResult').html("Friendly URLs are not working. This is most likely because a rewrite module isn't configured "
+ "correctly on your site. You may need to get your web host or server administrator to do this for you: "
+ "<ul>"
+ "<li><strong>mod_rewrite</strong> or other rewrite module is enabled on your web server</li>"
+ "<li><strong>AllowOverride All</strong> is set for the directory where SilverStripe is installed</li>"
+ "</ul>");
}
}
});
}
</script>
<noscript>
<li><a href="$destinationURL">Click here</a> to check friendly URLs are working. If you get a 404 then something is wrong.</li>
</noscript>
HTML;
}
/**
* Show an installation status message.
* The output differs depending on whether this is CLI or web based
*
* @param string $msg
*/
public function statusMessage($msg)
{
echo "<li>$msg</li>\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);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 B

View File

@ -1,49 +0,0 @@
$(document).ready(function () {
/**
* 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();
});
// 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;
}
// Process
$('#saving_top').hide();
$(this).val('Installing SilverStripe...');
return true;
});
/**
* 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;
});
});

View File

@ -1,593 +0,0 @@
/* This file is manually maintained, it is not generated from SCSS sources */
body{
font-family:Arial,san-serif;
margin-bottom:18px;
width:940px;
margin:0 auto 18px;
background-color:#f4f4f4;
}
body,body p{
font-size:13px;
line-height:18px;
color:#333;
}
body p{
margin-bottom:18px;
}
body a{
color:#0973a6;
}
body h1,body h2,body h3,body h4,body h5,body h6{
color:#222;
font-family:inherit;
font-weight:700;
margin:0;
margin:27px 0 9px;
text-rendering:optimizelegibility;
clear:both;
text-shadow:0 1px 0 #fff;
}
body h1 small,body h2 small,body h3 small,body h4 small,body h5 small,body h6 small{
font-weight:400;
font-size:12px;
color:#666;
}
body h1{
font-size:36px;
background: transparent url("../images/logo.gif") no-repeat left top;
text-indent:-9999px;
height:164px;
width:161px;
float:left;
padding-right:40px;
border-right:1px solid #b1c0c5;
margin-right:40px;
}
body h1,body h2{
line-height:36px;
letter-spacing:-.5px;
}
body h2{
font-size:34px;
}
body h3{
font-size:18px;
line-height:27px;
}
body h4{
font-size:14px;
margin:18px 0 9px;
}
body h4,body h5{
line-height:18px;
}
body h5{
font-size:12px;
margin:18px 0 0;
}
body #Header h1{
margin-top:45px;
margin-bottom:27px;
}
body #Header h3{
margin-top:-10px;
}
body .clear{
clear:both;
}
body .left{
float:left;
}
body .message{
padding:2px 18px;
margin-bottom:18px;
-moz-border-radius-topleft:3px;
-moz-border-radius-topright:3px;
-moz-border-radius-bottomright:3px;
-moz-border-radius-bottomleft:3px;
border-radius:3px 3px 3px 3px;
}
body .message p{
margin:11px 0 13px;
}
body .message.warning{
background-color:#fcf8f2;
border:1px solid #ffc28b;
}
body .message.error{
background-color:#fdf1f3;
border:1px solid #f8c3cd;
}
body .message ul{
margin-left:18px;
margin-top:-9px;
}
body .helpText{
float:right;
width:425px;
padding-left:20px;
color:#666;
margin-top:0;
background: transparent url("../images/question.png") no-repeat left 1px;
}
body .helpText.requirementsHelpText{
margin-top:17px;
}
body .typography table{
margin:9px 0 27px;
border-collapse:collapse;
width:100%;
}
body .typography table thead td,body .typography table thead th{
font-weight:700;
vertical-align:bottom;
padding:12px;
}
body .typography table td,body .typography table th{
padding:8px 12px;
text-align:left;
}
body .typography table td{
vertical-align:top;
border-top:0;
background-color:#fff;
}
body .typography table tbody tr:nth-child(odd) td,body .typography table tbody tr:nth-child(odd) th{
background-color:#fcfcfc;
}
body .typography table tbody tr:hover td,body .typography table tbody tr:hover th{
background-color:#f6f6f6;
}
body .typography table tfoot{
font-style:italic;
color:#888;
}
body .typography input,body .typography select,body .typography textarea{
width:420px;
margin-bottom:9px;
color:#707070;
border:1px solid #ddd;
display:inline-block;
height:18px;
padding:4px 6px;
line-height:18px;
font-size:13px;
-moz-border-radius-topleft:3px;
-moz-border-radius-topright:3px;
-moz-border-radius-bottomright:3px;
-moz-border-radius-bottomleft:3px;
border-radius:3px 3px 3px 3px;
}
body .typography input,body .typography textarea{
-webkit-transition:border .2s linear,-webkit-box-shadow .2s linear;
transition:border .2s linear,box-shadow .2s linear;
box-shadow:inset 0 1px 3px rgba(0,0,0,.1);
}
body .typography input:focus,body .typography textarea:focus{
outline:0;
border-color:rgba(82,168,236,.8);
box-shadow:inset 0 1px 3px rgba(0,0,0,.1),0 0 4px rgba(82,168,236,.6);
}
body .typography input[type=checkbox]:focus,body .typography input[type=file]:focus,body .typography select:focus{
box-shadow:none;
outline:1px dotted #666;
}
body .typography select{
height:26px;
}
body .typography option{
line-height:27px;
font-size:12px;
padding:2px 6px;
color:#666;
}
body .typography label{
width:auto;
float:none;
padding-top:0;
margin:0 0 5px;
text-align:left;
display:block;
}
body .typography .fields{
float:left;
}
body .typography input.action{
text-align:center;
font-weight:700;
margin:9px 0 27px;
padding:6px 8px;
width:200px;
width:auto;
color:#222;
border:1px solid #aaa;
text-shadow:0 1px 0 #eee;
font-size:13px;
float:none;
height:auto;
background:#fbfbfb;
background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#bbb));
background:-webkit-linear-gradient(top,#fbfbfb,#bbb);
background:-webkit-gradient(linear,left top,left bottom,from(#fbfbfb),to(#bbb));
background:linear-gradient(180deg,#fbfbfb 0,#bbb);
-moz-border-radius-topleft:3px;
-moz-border-radius-topright:3px;
-moz-border-radius-bottomright:3px;
-moz-border-radius-bottomleft:3px;
border-radius:3px 3px 3px 3px;
box-shadow:0 1px 0 0 #fff;
background-color:#ddd;
}
.lt-ie9 body .typography input.action{
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fbfbfb",endColorstr="#bbb",GradientType=0);
}
body .typography input.action:hover{
box-shadow:0 1px 2px 0 #ccc;
background:#fbfbfb;
background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#ccc));
background:-webkit-linear-gradient(top,#fbfbfb,#ccc);
background:-webkit-gradient(linear,left top,left bottom,from(#fbfbfb),to(#ccc));
background:linear-gradient(180deg,#fbfbfb 0,#ccc);
}
.lt-ie9 body .typography input.action:hover{
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fbfbfb",endColorstr="#ccc",GradientType=0);
}
body .typography input.action:active,body .typography input.action:focus{
box-shadow:0 1px 0 0 #fff;
background:#fbfbfb;
background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#bbb));
background:-webkit-linear-gradient(top,#fbfbfb,#bbb);
background:-webkit-gradient(linear,left top,left bottom,from(#fbfbfb),to(#bbb));
background:linear-gradient(180deg,#fbfbfb 0,#bbb);
}
.lt-ie9 body .typography input.action:active,.lt-ie9 body .typography input.action:focus{
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fbfbfb",endColorstr="#bbb",GradientType=0);
}
body .typography input.action:focus,body .typography input.action:hover{
cursor:pointer;
}
body .typography input[type=checkbox],body .typography input[type=radio]{
border:medium none;
height:auto;
line-height:normal;
padding:0;
width:auto;
margin-right:6px;
float:left;
margin-top:3px;
}
body .typography #install_button{
font-size:20px;
color:#fff;
border-color:#78a127 #78a127 #59781d;
text-shadow:0 1px 1px #4d7326;
padding:8px 14px;
background-color:green;
background:#80bf40;
background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#80bf40),color-stop(100%,#59862d));
background:-webkit-linear-gradient(top,#80bf40,#59862d);
background:-webkit-gradient(linear,left top,left bottom,from(#80bf40),to(#59862d));
background:linear-gradient(180deg,#80bf40 0,#59862d);
box-shadow:0 1px 0 0 #fff;
}
.lt-ie9 body .typography #install_button{
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#80BF40",endColorstr="#59862D",GradientType=0);
}
body .typography #install_button:hover{
box-shadow:0 1px 3px 0 #bbb;
}
body .typography #install_button:active,body .typography #install_button:focus{
box-shadow:0 1px 0 0 #fff;
background:#80bf40;
background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#80bf40),color-stop(100%,#59862d));
background:-webkit-linear-gradient(top,#80bf40,#59862d);
background:-webkit-gradient(linear,left top,left bottom,from(#80bf40),to(#59862d));
background:linear-gradient(180deg,#80bf40 0,#59862d);
}
.lt-ie9 body .typography #install_button:active,.lt-ie9 body .typography #install_button:focus{
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#80BF40",endColorstr="#59862D",GradientType=0);
}
body .typography #install_button[disabled=disabled]{
border:1px solid #aaa;
border-color:#bbb #bbb #aaa;
color:#999;
text-shadow:0 1px 0 #eee;
background:#fbfbfb;
background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#bbb));
background:-webkit-linear-gradient(top,#fbfbfb,#bbb);
background:-webkit-gradient(linear,left top,left bottom,from(#fbfbfb),to(#bbb));
background:linear-gradient(180deg,#fbfbfb 0,#bbb);
}
.lt-ie9 body .typography #install_button[disabled=disabled]{
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fbfbfb",endColorstr="#bbb",GradientType=0);
}
body .typography #install_button[disabled=disabled]:hover{
box-shadow:0 1px 0 0 #fff;
}
body #Container{
margin-bottom:40px;
}
body #Container h3.sectionHeading{
padding-top:27px;
border-top:1px solid #b1c0c5;
clear:both;
}
body #Container #Header{
margin-bottom:30px;
height:200px;
}
body #Container #Header div.left{
width:698px;
margin-top:47px;
}
body #Container #Navigation{
display:none;
}
body h5.requirement{
padding:12px 18px;
font-size:14px;
border:1px solid #798c93;
border-top:1px solid #8d9da3;
margin:0;
color:#fff;
position:relative;
text-shadow:0 -1px 0 #71858c;
-moz-border-radius-topleft:3px;
-moz-border-radius-topright:3px;
-moz-border-radius-bottomright:3px;
-moz-border-radius-bottomleft:3px;
border-radius:3px 3px 3px 3px;
box-shadow:0 1px 0 0 #fff;
background-color:#eee;
background:#b1c0c5;
background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#b1c0c5),color-stop(100%,#7f9198));
background:-webkit-linear-gradient(top,#b1c0c5,#7f9198);
background:-webkit-gradient(linear,left top,left bottom,from(#b1c0c5),to(#7f9198));
background:linear-gradient(180deg,#b1c0c5 0,#7f9198);
}
.lt-ie9 body h5.requirement{
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#B1C0C5",endColorstr="#7F9198",GradientType=0);
}
body h5.requirement span{
font-weight:400;
font-size:12px;
padding:3px 6px;
margin-left:5px;
text-shadow:none;
background-color:#fafbfb;
-moz-border-radius-topleft:2px;
-moz-border-radius-topright:2px;
-moz-border-radius-bottomright:2px;
-moz-border-radius-bottomleft:2px;
border-radius:2px 2px 2px 2px;
box-shadow:0 0 2px 0 #7f9198;
}
body h5.requirement.good span{
color:#359318;
}
body h5.requirement.warning span{
color:#e07127;
}
body h5.requirement.error span{
color:#c61414;
}
body h5.requirement a{
font-size:11px;
right:9px;
position:absolute;
line-height:19px;
margin:0 0 0 30px;
color:#fff;
text-decoration:none;
font-weight:400;
padding-right:21px;
background: transparent url("../images/arrows.png") no-repeat right top;
}
body h5.requirement a:hover{
background: transparent url("../images/arrows.png") no-repeat right -40px;
}
body table.testResults{
border-top:0;
margin-top:-1px;
margin-bottom:9px;
box-shadow:0 1px 0 0 #fff;
-moz-border-radius-topleft:3px;
-moz-border-radius-topright:3px;
-moz-border-radius-bottomright:3px;
-moz-border-radius-bottomleft:3px;
border-radius:3px 3px 3px 3px;
overflow:hidden;
}
body table.testResults tr.good{
display:none;
border:0;
}
body table.testResults tr.good td{
color:#359318;
}
body table.testResults tr.warning{
border:0;
}
body table.testResults tr.warning td{
color:#e07127;
}
body table.testResults tr.error{
border:0;
color:#c61414;
}
body table.testResults td{
border:1px solid #ddd;
width:50%;
}
body #database_selection,body #Themes{
list-style:none;
margin:0;
margin-bottom:18px;
padding-left:0;
}
body #database_selection li,body #Themes li{
clear:left;
padding:3px 0;
}
body #database_selection li .dbfields,body #Themes li .dbfields{
padding:12px;
border:1px solid #ddd;
background-color:#fafafa;
margin-bottom:9px;
-moz-border-radius-topleft:3px;
-moz-border-radius-topright:3px;
-moz-border-radius-bottomright:3px;
-moz-border-radius-bottomleft:3px;
border-radius:3px 3px 3px 3px;
box-shadow:inset 0 0 3px 0 #ddd;
box-shadow:0 1px 0 0 #fff;
}
body ul#Themes{
float:left;
width:445px;
}
body .databaseError{
width:422px;
}
body #Footer{
margin-top:67px;
margin-bottom:18px;
}
body #Footer p{
font-size:12px;
color:#999;
}
#adminAcc,#devHelp,#localeHelp{
padding-top:20px;
}
#devHelp,#devSection{
height:18em;
}
#use_environment_field{
margin-bottom:25px;
background-color:#fafafa;
border:1px solid #ddd;
border-radius:3px 3px 3px 3px;
box-shadow:0 1px 0 0 #fff;
margin-bottom:9px;
padding:10px 10px 8px;
}
#use_environment_field input{
float:left;
margin-right:5px;
}
.databaseError ul{
margin-bottom:0;
}
.databaseError li,.databaseError ul{
margin-left:0;
padding-left:0;
}
#Layout p.goodInstall,.goodInstall{
color:#359318;
}
.goodInstall{
padding:.5em;
background-color:#e2fee1;
border:1px solid #43cb3e;
overflow:hidden;
line-height:18px;
padding:10px;
}
.goodInstall a{
float:right;
font-size:18px;
padding:0 2px 2px 0;
font-weight:700;
}

View File

@ -1,279 +0,0 @@
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
<title>SilverStripe CMS / Framework Installation</title>
<base href="<?php echo htmlentities($base); ?>" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<script type="application/javascript" src="//code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="application/javascript" src="<?=$clientPath; ?>/js/install.js"></script>
<link rel="stylesheet" type="text/css" href="<?=$clientPath; ?>/styles/install.css">
<link rel="shortcut icon" href="favicon.ico">
</head>
<body>
<div id="BgContainer">
<div id="Container">
<div id="Header">
<h1>SilverStripe</h1>
<div class="left">
<h2>CMS / Framework Installation <?php if($silverstripe_version) echo "<small>Version $silverstripe_version</small>"; ?></h2>
<p>Thanks for choosing to use SilverStripe! Please follow the instructions below and you should be up in running in no time.<br>
If you get stuck, head over to the <a href="http://silverstripe.org/community/forums/installing-silverstripe" target="_blank">installation forum</a>, or check out our page of <a href="http://www.silverstripe.org/hosting" target="_blank">suggested web hosting options</a> known to work with SilverStripe.
</p>
</div>
</div>
<div id="Navigation">&nbsp;</div>
<div class="clear"><!-- --></div>
<div id="Layout">
<div class="typography">
<form action="install.php" method="post">
<?php if($hasErrorOtherThanDatabase): ?>
<p class="message error">
You aren't currently able to install the software. Please <a href="#requirements">see below</a> for details.<br>
If you are having problems meeting the requirements, see the <a href="http://doc.silverstripe.org/framework/en/installation/server-requirements" target="_blank">server requirements</a>.
</p>
<?php if ($phpIniLocation): ?>
<p class="message warning">Your php.ini file is located at <?=$phpIniLocation; ?></p>
<?php endif; ?>
<?php else: ?>
<?php if($alreadyInstalled): ?>
<div class="message warning">
<p><strong>Note:</strong> SilverStripe is already installed here.<br>
If you choose to reinstall SilverStripe, your current settings will be replaced</p>
</div>
<?php elseif($req->hasWarnings()): ?>
<div class="message warning">
<p>There are some issues that we recommend you look at before installing, however, you are still able to install the software.
<br>Please see below for details. If you are having problems meeting the requirements, see the <a href="http://doc.silverstripe.org/framework/en/installation/server-requirements" target="_blank">server requirements</a>.</p>
</div>
<?php elseif(!$dbReq->hasErrors() && !$adminReq->hasErrors()): ?>
<div class="message goodInstall"><p>You're ready to install! Please confirm the configuration options below. <a href="#install">Install SilverStripe</a></p>
</div>
<?php endif; ?>
<?php if($dbReq->hasErrors()): ?>
<div class="message error">
<p>The database details don't appear to be correct. Please <a href="#database_credentials">review and correct</a> before installing.</p>
</div>
<?php endif; ?>
<?php if($adminReq->hasErrors()): ?>
<div class="message error">
<p>Please <a href="#AdminAccount">enter an email address and password</a> for the default administrator account before installing.</p>
</div>
<?php endif; ?>
<?php endif; ?>
<h3 class="sectionHeading" id="requirements">Requirements <small>Step 1 of 5</small></h3>
<?php $req->showTable(); ?>
<?php $dbReq->showTable(); ?>
<p class="helpText requirementsHelpText">
Read more about our <a href="http://doc.silverstripe.org/framework/en/installation/server-requirements" target="_blank">server requirements</a>.
</p>
<div class="action">
<input type="submit" class="action" value="Re-check requirements">
</div>
<div class="clear"><!-- --></div>
<h3 class="sectionHeading">Database Configuration <small>Step 2 of 5</small></h3>
<div id="database_credentials" class="section">
<?php $dbReq->showTable("Database Configuration"); ?>
<p id="dbHelp" class="helpText">
SilverStripe stores its content in a relational SQL database. Please provide the username and password to connect to the server here.
If this account has permission to create databases, then we will create the database for you; otherwise, you must give the name of a
database that already exists.<br><br>
<strong>Other databases:</strong><br>
Databases in the list that are greyed out cannot currently be used. Click on them for more information and possible remedies.
</p>
<div class="fields">
<div class="field">
<ul id="database_selection">
<?php
foreach ($databaseClasses as $class => $details) {
$checked = ($databaseConfig['type'] == $class) ? ' checked="checked"' : '';
$disabled = $help = '';
$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 = '<li style="width:auto">'.$details['missingExtensionText'].'</li>';
$helpText .= '<li style="width:auto">'.$details['missingModuleText'].'</li>';
} else if ($details['supported'] && !$details['hasModule']) {
$help = 'PHP has the required extension, but SilverStripe is missing the module';
$helpText = '<li style="width:auto">'.$details['missingModuleText'].'</li>';
} else if (!$details['supported'] && $details['hasModule']) {
$help = 'SilverStripe has the module installed, but PHP is missing the required extension';
$helpText = '<li style="width:auto">'.$details['missingExtensionText'].'</li>';
}
$help .= "<ul>$helpText</ul>";
}
echo "<li>";
echo "<input id=\"$class\" class=\"databaseClass\" type=\"radio\" name=\"db[type]\" value=\"$class\"$checked $disabled>";
echo "<label class=\"left\" ".($help || $disabled ? 'style="font-weight:normal;color:grey" ' : 'style="color:green"')."for=\"$class\">{$details['title']}</label>";
if ($help) {
echo '<div class="message error databaseError"><p>'.$help.'</p></div>';
}
// generate db-specific config fields
echo $checked ? '<div class="dbfields">' : '<div class="dbfields" style="display: none;">';
if(isset($details['fields'])) foreach($details['fields'] as $fieldName => $fieldSpec) {
$fieldTitle = $fieldSpec['title'];
$fieldType = ($fieldName === 'password') ? 'password' : 'text';
// Get display value
if (isset($databaseConfig[$fieldName]) && $databaseConfig['type'] == $class) {
$value = $databaseConfig[$fieldName];
} elseif (isset($fieldSpec['default'])) {
$value = $fieldSpec['default'];
} else {
$value = null;
}
// attributes
$attrs = array(
'id' => "db_{$class}_{$fieldName}",
'class' => 'text',
'type' => $fieldType,
'name' => "db[$class][$fieldName]",
'value' => $value,
);
$attrHTML = '';
foreach($attrs as $attrName => $attrValue) $attrHTML .= "$attrName=\"" . htmlspecialchars($attrValue) . '"';
if(isset($fieldSpec['attributes'])) $attrs = array_merge($attrs, $fieldSpec['attributes']);
// html
echo "<div class=\"field\">";
echo "<label for=\"db_{$class}_$fieldName\">$fieldTitle:</label>";
echo "<span class=\"middleColumn\">";
echo "<input $attrHTML>";
echo "</span>";
echo "</div>";
}
echo '</div>';
echo "</li>";
}
?>
</ul>
<div id="use_environment_field" class="field">
<input id="use_environment" type="checkbox" name="useEnv" <?php if($usingEnv) echo "checked=\"checked\"" ?>>
<label for="use_environment">Use environment variables for configuration (<a href="http://doc.silverstripe.org/framework/en/topics/environment-management" target="_blank">?</a>)</label>
</div>
</div>
</div>
</div>
<div class="clear"><!-- --></div>
<div class="action">
<input type="submit" class="action" value="Re-check requirements">
</div>
<h3 class="sectionHeading">CMS Admin Account <small>Step 3 of 5</small></h3>
<div id="AdminAccount" class="section">
<div class="form__fieldGroup">
<p class="helpText">We will set up the first administrator account for you automatically. You can change these details later in the "Security" section within the CMS.</p>
<div class="field">
<label for="admin_username">Email:</label>
<span class="middleColumn">
<input type="text" class="text" name="admin[username]" id="admin_username" value="<?=htmlspecialchars($adminConfig['username'], ENT_QUOTES, 'UTF-8'); ?>" <?php if($usingEnv && getenv('SS_DEFAULT_ADMIN_USERNAME')) echo 'disabled="disabled"' ?>>
</span>
</div>
<div class="field">
<label for="admin_password">Password:</label>
<span class="middleColumn">
<input type="password" class="text" name="admin[password]" id="admin_password" value="<?=htmlspecialchars($adminConfig['password'], ENT_QUOTES, 'UTF-8'); ?>" <?php if($usingEnv && getenv('SS_DEFAULT_ADMIN_PASSWORD')) echo 'disabled="disabled"' ?>>
</span>
</div>
</div>
<div class="form__fieldGroup">
<p class="helpText">
"Default language" determines the default locale settings
(for dates, currencies, etc.), as well as the default language
of the CMS interface. This can be changed for each user.
<br>
<strong>Warning:</strong> The CMS interface may be missing translations in certain locales.
</p>
<div class="field">
<label for="locale">Default language:</label>
<span class="middleColumn">
<select name="locale" id="locale">
<?php
foreach ($locales as $code => $title) {
$selected = ($code === $locale) ? ' selected="selected"' : '';
echo "<option$selected value=\"$code\">{$title}</option>\n";
}
?>
</select>
</span>
</div>
<div class="clear"><!-- --></div>
</div>
</div>
<div class="action">
<input type="submit" class="action" value="Re-check requirements">
</div>
<h3 class="sectionHeading">Theme selection <small>Step 4 of 5</small></h3>
<p class="helpText">You can change the theme or <a href="http://addons.silverstripe.org/add-ons?type=theme">download</a> another from the SilverStripe website after installation.</p>
<ul id="Themes">
<li><input type="radio" name="template" value="simple" id="Simple"
<?php if($theme === 'simple'): ?>checked="checked"<?php endif; ?>><label for="Simple"><a href="https://github.com/silverstripe-themes/silverstripe-simple">Simple</a> - our default theme ready to use, or begin the <a href="http://www.silverstripe.org/learn/lessons" target="_blank">lessons</a>.</label></li>
<li><input type="radio" name="template" value="tutorial" id="EmptyTemplate" <?php if($theme === 'tutorial'): ?>checked="checked"<?php endif; ?>><label for="EmptyTemplate">Empty template</label></li>
</ul>
<h3 class="sectionHeading" id="install">Confirm Install <small>Step 5 of 5</small></h3>
<?php if($hasErrorOtherThanDatabase): ?>
<p class="error">
You aren't currently able to install the software. Please <a href="#requirements">see above</a> for details.<br>
If you are having problems meeting the requirements, see the <a href="http://doc.silverstripe.org/doku.php?id=server-requirements">server requirements page</a>.
</p>
<?php else: ?>
<p id="stats-container">
<input type="checkbox" id="stats" name="stats" checked="checked">
<label for="stats">Send information about my webserver to silverstripe.org<br />
<small>(anonymous version information, used for statistical purposes)</small>
</label><p>
<p>
<?php if($alreadyInstalled): ?>
<input id="install_button" type="submit" class="action mustconfirm" name="reinstall" value="Reinstall SilverStripe">
<?php else: ?>
<input id="install_button" type="submit" class="action" name="go" value="Install SilverStripe">
<?php endif; ?>
<span id="saving_top" style="display: none">
&nbsp;
<img src="<?=$clientPath; ?>/images/network-save.gif" alt="Saving">
(this will take a minute or so)
</span>
</p>
<?php endif ?>
</form>
</div>
</div>
<div class="clear"><!-- --></div>
</div>
<div id="Footer">
<div class="footerTop"><!-- --></div>
<p><a href="http://silverstripe.org">SilverStripe Open Source CMS / Framework</a> | Copyright &copy; <?=date('Y'); ?> SilverStripe Limited</p>
</div>
</div>
</body>
</html>

View File

@ -1,25 +0,0 @@
<?php
/************************************************************************************
************************************************************************************
** **
** If you can read this text in your browser then you don't have PHP installed. **
** Please install PHP 5.5.0 or higher. **
** **
************************************************************************************
************************************************************************************/
/**
* PHP version check. Make sure we've got at least PHP 5.6.0 in the most friendly way possible
*/
if (version_compare(phpversion(), '5.6.0', '<')) {
header($_SERVER['SERVER_PROTOCOL'] . " 500 Server Error");
echo str_replace(
'$PHPVersion',
phpversion(),
file_get_contents(__DIR__ . "/php5-required.html")
);
die();
}
include(__DIR__ . '/install5.php');

View File

@ -1,156 +0,0 @@
<?php
/************************************************************************************
************************************************************************************
** **
** If you can read this text in your browser then you don't have PHP installed. **
** Please install PHP 5.5.0 or higher. **
** **
************************************************************************************
************************************************************************************/
namespace SilverStripe\Dev\Install;
// Back up original ini config
$originalIni = [];
$iniSet = function ($name, $value) use (&$originalIni) {
if (!isset($originalIni[$name])) {
$originalIni[$name] = ini_get($name);
}
ini_set($name, $value);
};
// speed up mysql_connect timeout if the server can't be found
$iniSet('mysql.connect_timeout', 5);
// Don't die half was through installation; that does more harm than good
$iniSet('max_execution_time', 0);
// set display_errors php setting to on to force installer to avoid blank screen of death.
// get the original value so it can be used in PHP requirement checks later in this script.
$iniSet('display_errors', '1');
error_reporting(E_ALL | E_STRICT);
// Attempt to start a session so that the username and password can be sent back to the user.
if (function_exists('session_start') && !session_id()) {
session_start();
}
// require composers autoloader
require_once __DIR__ . '/../../includes/autoload.php';
$usingEnv = empty($_POST) || !empty($_REQUEST['useEnv']);
// Set default locale, but try and sniff from the user agent
$locale = isset($_POST['locale']) ? $_POST['locale'] : 'en_US';
// Discover which databases are available
DatabaseAdapterRegistry::autodiscover();
// Determine which external database modules are USABLE
$databaseClasses = DatabaseAdapterRegistry::get_adapters();
foreach ($databaseClasses as $class => $details) {
$helper = DatabaseAdapterRegistry::getDatabaseConfigurationHelper($class);
$databaseClasses[$class]['hasModule'] = !empty($helper);
}
// Build config from config / environment / request
$config = new InstallConfig();
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses, true);
$adminConfig = $config->getAdminConfig($_REQUEST, true);
$alreadyInstalled = $config->alreadyInstalled();
$silverstripe_version = $config->getFrameworkVersion();
$sendStats = $config->canSendStats($_REQUEST);
$locales = $config->getLocales();
$theme = $config->getTheme($_REQUEST);
// Check requirements
$req = new InstallRequirements();
$req->check($originalIni);
if ($req->isIIS()) {
$webserverConfigFile = 'web.config';
} else {
$webserverConfigFile = '.htaccess';
}
$hasErrorOtherThanDatabase = false;
$hasOnlyWarnings = false;
$phpIniLocation = php_ini_loaded_file();
if ($req->hasErrors()) {
$hasErrorOtherThanDatabase = true;
} elseif ($req->hasWarnings()) {
$hasOnlyWarnings = true;
}
$dbReq = new InstallRequirements();
if ($databaseConfig) {
$dbReq->checkDatabase($databaseConfig);
}
$adminReq = new InstallRequirements();
if ($adminConfig) {
$adminReq->checkAdminConfig($adminConfig);
}
// Actual processor
$installFromCli = (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == 'install');
// CLI-install error message. exit(1) will halt any makefile.
if ($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) {
echo "Cannot install due to errors:\n";
$req->listErrors();
$dbReq->listErrors();
exit(1);
}
// Path to client resources (copied through silverstripe/vendor-plugin)
$base = rtrim(BASE_URL, '/') . '/';
$clientPath = RESOURCES_DIR . (PUBLIC_DIR
? '/vendor/silverstripe/framework/src/Dev/Install/client'
: '/silverstripe/framework/src/Dev/Install/client');
// 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
$inst = new Installer();
$inst->install([
'usingEnv' => $usingEnv,
'locale' => $locale,
'theme' => $theme,
'version' => $silverstripe_version,
'db' => $databaseConfig,
'admin' => $adminConfig,
'stats' => $sendStats,
]);
return;
}
// Sanitise config prior to rendering config-form.html
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses, false);
$adminConfig = $config->getAdminConfig($_REQUEST, false);
// config-form.html vars (placeholder to prevent deletion)
[
$base,
$theme,
$clientPath,
$adminConfig,
$databaseConfig,
$usingEnv,
$silverstripe_version,
$locale,
$locales,
$webserverConfigFile,
$hasErrorOtherThanDatabase,
$hasOnlyWarnings, // If warnings but not errors
$phpIniLocation,
];
include(__DIR__ . '/config-form.html');

View File

@ -1,37 +0,0 @@
<html>
<head>
<title>PHP 5.6.0 is required</title>
<link rel="stylesheet" type="text/css" href="framework/src/Dev/Install/client/styles/install.css">
</head>
<body>
<div id="BgContainer">
<div id="Container">
<div id="Header">
<h1>PHP 5.6.0 required</h1>
<div class="left">
<h3>To run SilverStripe, please install PHP 5.6.0 or greater.</h3>
<p>We have detected that you are running PHP version <b>$PHPVersion</b>. In order to run SilverStripe,
you must have PHP version 5.6.0 or higher.<p/>
<p>If you are running on a shared host, you may need to ask your hosting provider how to do this.</p>
</div>
</div>
<div id="Navigation">&nbsp;</div>
<div class="clear"><!-- --></div>
<div id="Layout">
<div class="typography">
</div>
</div>
<div class="clear"><!-- --></div>
</div>
<div id="Footer">
<div class="footerTop"><!-- --></div>
<p><a href="http://silverstripe.org">SilverStripe Open Source CMS</a> | Copyright &copy; 2017 SilverStripe Limited</p>
</div>
</div>
</body>
</html>

View File

@ -1,54 +0,0 @@
<?php
namespace SilverStripe\Dev\Tests\Install;
use SilverStripe\Dev\Install\InstallRequirements;
use SilverStripe\Dev\SapphireTest;
class InstallRequirementsTest extends SapphireTest
{
public function testIIS()
{
$requirements = new InstallRequirements();
$_SERVER['SERVER_SIGNATURE'] = 'Microsoft-IIS/10.0';
// Test server
$this->assertEquals('Microsoft-IIS/10.0', $requirements->findWebserver());
// True conditions
$this->assertTrue($requirements->isIIS());
$this->assertTrue($requirements->isIIS(10));
$this->assertTrue($requirements->isIIS('10.0'));
$this->assertTrue($requirements->isIIS(9));
// Negative - Based on number
$this->assertFalse($requirements->isIIS(11));
$_SERVER['SERVER_SIGNATURE'] = 'Microsoft-IIS/6.0';
$this->assertFalse($requirements->isIIS());
$_SERVER['SERVER_SIGNATURE'] = 'Microsoft-IIS/6.5';
$this->assertFalse($requirements->isIIS());
// Negative - Based on string
$_SERVER['SERVER_SOFTWARE'] = 'lighttpd/1.4.33';
$this->assertFalse($requirements->isIIS());
$_SERVER['SERVER_SOFTWARE'] = 'Apache/2.4.25 (Unix) PHP/5.6.30 LibreSSL/2.2.7';
$this->assertFalse($requirements->isIIS());
}
public function testApache()
{
$requirements = new InstallRequirements();
$_SERVER['SERVER_SIGNATURE'] = '';
$_SERVER['SERVER_SOFTWARE'] = 'Apache/2.4.25 (Unix) PHP/5.6.30 LibreSSL/2.2.7';
// Test server
$this->assertEquals('Apache/2.4.25 (Unix) PHP/5.6.30 LibreSSL/2.2.7', $requirements->findWebserver());
// True conditions
$this->assertTrue($requirements->isApache());
// False conditions
$_SERVER['SERVER_SOFTWARE'] = 'lighttpd/1.4.33';
$this->assertFalse($requirements->isApache());
}
}