+
+
Installing SilverStripe...
+
+
I am now running through the installation steps (this should take about 30 seconds)
+
+
If you receive a fatal error, refresh this page to continue the installation
+
+ installHeader();
+
+ $webserver = $this->findWebserver();
+ $isIIS = $this->isIIS();
+ $isApache = $this->isApache();
+
+ flush();
+
+ if (isset($config['stats'])) {
+ if (file_exists(FRAMEWORK_PATH . '/silverstripe_version')) {
+ $silverstripe_version = file_get_contents(FRAMEWORK_PATH . '/silverstripe_version');
+ } else {
+ $silverstripe_version = "unknown";
+ }
+
+ $phpVersion = urlencode(phpversion());
+ $encWebserver = urlencode($webserver);
+ $dbType = $config['db']['type'];
+
+ // Try to determine the database version from the helper
+ $databaseVersion = $config['db']['type'];
+ $helper = $this->getDatabaseConfigurationHelper($dbType);
+ if ($helper && method_exists($helper, 'getDatabaseVersion')) {
+ $versionConfig = $config['db'][$dbType];
+ $versionConfig['type'] = $dbType;
+ $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($versionConfig));
+ }
+
+ $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$encWebserver";
+
+ if (isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
+ $url .= '&ID=' . $_SESSION['StatsID'];
+ }
+
+ @$_SESSION['StatsID'] = file_get_contents($url);
+ }
+
+ if (file_exists('mysite/_config.php')) {
+ // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly
+ // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them
+ $fh = fopen('mysite/_config.php', 'wb');
+ fclose($fh);
+ }
+
+ // Escape user input for safe insertion into PHP file
+ $theme = isset($_POST['template']) ? addcslashes($_POST['template'], "\'") : 'simple';
+ $locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\'") : 'en_US';
+ $type = addcslashes($config['db']['type'], "\'");
+ $dbConfig = $config['db'][$type];
+ foreach ($dbConfig as &$configValue) {
+ $configValue = addcslashes($configValue, "\\\'");
+ }
+ if (!isset($dbConfig['path'])) {
+ $dbConfig['path'] = '';
+ }
+ if (!$dbConfig) {
+ echo "Bad config submitted
";
+ print_r($config);
+ echo "
";
+ die();
+ }
+
+ // Write the config file
+ global $usingEnv;
+ if ($usingEnv) {
+ $this->statusMessage("Setting up 'mysite/_config.php' for use with environment variables...");
+ $this->writeToFile("mysite/_config.php", <<
statusMessage("Setting up 'mysite/_config.php'...");
+ // Create databaseConfig
+ $lines = array(
+ $lines[] = "\t'type' => '$type'"
+ );
+ foreach ($dbConfig as $key => $value) {
+ $lines[] = "\t'{$key}' => '$value'";
+ }
+ $databaseConfigContent = implode(",\n", $lines);
+ $this->writeToFile("mysite/_config.php", <<statusMessage("Setting up 'mysite/_config/config.yml'");
+ $this->writeToFile("mysite/_config/config.yml", <<checkModuleExists('cms')) {
+ $this->writeToFile("mysite/code/RootURLController.php", <<Your site is now set up. Start adding controllers to mysite to get started.";
+ }
+
+}
+PHP
+ );
+ }
+
+ // Write the appropriate web server configuration file for rewriting support
+ if ($this->hasRewritingCapability()) {
+ if ($isApache) {
+ $this->statusMessage("Setting up '.htaccess' file...");
+ $this->createHtaccess();
+ } elseif ($isIIS) {
+ $this->statusMessage("Setting up 'web.config' file...");
+ $this->createWebConfig();
+ }
+ }
+
+ // Mock request
+ $session = new Session(isset($_SESSION) ? $_SESSION : array());
+ $request = new HTTPRequest('GET', '/');
+ $request->setSession($session);
+
+ // Install kernel (fix to dev)
+ $kernel = new AppKernel(BASE_PATH);
+ $kernel->setEnvironment(Kernel::DEV);
+ $app = new HTTPApplication($kernel);
+
+ // Build db within HTTPApplication
+ $app->execute($request, function (HTTPRequest $request) use ($config) {
+ // Start session and execute
+ $request->getSession()->init();
+
+ // 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())
+ $adminMember = DefaultAdminService::singleton()->findOrCreateDefaultAdmin();
+ $adminMember->Email = $config['admin']['username'];
+ $adminMember->Password = $config['admin']['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', $config['admin']['username']);
+ $request->getSession()->set('password', $config['admin']['password']);
+ $request->getSession()->save();
+ }, true);
+
+ // Check result of install
+ if (!$this->errors) {
+ if (isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) {
+ $this->statusMessage("Checking that friendly URLs work...");
+ $this->checkRewrite();
+ } else {
+ $token = new ParameterConfirmationToken('flush', $request);
+ $params = http_build_query($token->params());
+
+ $destinationURL = 'index.php/' .
+ ($this->checkModuleExists('cms') ? "home/successfullyinstalled?$params" : "?$params");
+
+ echo <<SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...
+
+
+HTML;
+ }
+ }
+
+ return $this->errors;
+ }
+
+ public function writeToFile($filename, $content)
+ {
+ $base = $this->getBaseDir();
+ $this->statusMessage("Setting up $base$filename");
+
+ if ((@$fh = fopen($base . $filename, 'wb')) && fwrite($fh, $content) && fclose($fh)) {
+ return true;
+ }
+ $this->error("Couldn't write to file $base$filename");
+ return false;
+ }
+
+ public function createHtaccess()
+ {
+ $start = "### SILVERSTRIPE START ###\n";
+ $end = "\n### SILVERSTRIPE END ###";
+
+ $base = dirname($_SERVER['SCRIPT_NAME']);
+ if (defined('DIRECTORY_SEPARATOR')) {
+ $base = str_replace(DIRECTORY_SEPARATOR, '/', $base);
+ } else {
+ $base = str_replace("\\", '/', $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 = <<
+ Order deny,allow
+ Deny from all
+ Allow from 127.0.0.1
+
+
+# Deny access to IIS configuration
+
+ Order deny,allow
+ Deny from all
+
+
+# Deny access to YAML configuration files which might include sensitive information
+
+ Order allow,deny
+ Deny from all
+
+
+# Route errors to static pages automatically generated by SilverStripe
+ErrorDocument 404 /assets/error-404.html
+ErrorDocument 500 /assets/error-500.html
+
+
+
+ # Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
+
+ DirectoryIndex disabled
+
+
+ SetEnv HTTP_MOD_REWRITE On
+ RewriteEngine On
+ $baseClause
+ $cgiClause
+
+ # Deny access to potentially sensitive files and folders
+ RewriteRule ^vendor(/|$) - [F,L,NC]
+ RewriteRule silverstripe-cache(/|$) - [F,L,NC]
+ RewriteRule composer\.(json|lock) - [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.
+ RewriteCond %{REQUEST_URI} ^(.*)$
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule .* framework/main.php?url=%1 [QSA]
+
+TEXT;
+
+ if (file_exists('.htaccess')) {
+ $htaccess = file_get_contents('.htaccess');
+
+ 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('.htaccess', $start . $rewrite . $end);
+ }
+
+ /**
+ * Writes basic configuration to the web.config for IIS
+ * so that rewriting capability can be use.
+ */
+ public function createWebConfig()
+ {
+ $content = <<
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+TEXT;
+
+ $this->writeToFile('web.config', $content);
+ }
+
+ public function checkRewrite()
+ {
+ $token = new ParameterConfirmationToken('flush', new HTTPRequest('GET', '/'));
+ $params = http_build_query($token->params());
+
+ $destinationURL = str_replace('install.php', '', $_SERVER['SCRIPT_NAME']) .
+ ($this->checkModuleExists('cms') ? "home/successfullyinstalled?$params" : "?$params");
+
+ echo <<Testing...
+
+
+HTML;
+ }
+
+ public function var_export_array_nokeys($array)
+ {
+ $retval = "array(\n";
+ foreach ($array as $item) {
+ $retval .= "\t'";
+ $retval .= trim($item);
+ $retval .= "',\n";
+ }
+ $retval .= ")";
+ return $retval;
+ }
+
+ /**
+ * Show an installation status message.
+ * The output differs depending on whether this is CLI or web based
+ *
+ * @param string $msg
+ */
+ public function statusMessage($msg)
+ {
+ echo "$msg\n";
+ flush();
+ }
+}
diff --git a/src/Dev/Install/install.php b/src/Dev/Install/install.php
index 6f1ab4b8d..69304eab5 100644
--- a/src/Dev/Install/install.php
+++ b/src/Dev/Install/install.php
@@ -24,4 +24,4 @@ if (version_compare(phpversion(), '5.5.0', '<')) {
die();
}
-include(__DIR__ . '/install.php5');
+include(__DIR__ . '/install5.php');
diff --git a/src/Dev/Install/install.php5 b/src/Dev/Install/install.php5
deleted file mode 100755
index d3a8a5349..000000000
--- a/src/Dev/Install/install.php5
+++ /dev/null
@@ -1,1767 +0,0 @@
- 'Afrikaans (South Africa)',
- 'ar_EG' => 'Arabic (Egypt)',
- 'hy_AM' => 'Armenian (Armenia)',
- 'ast_ES' => 'Asturian (Spain)',
- 'az_AZ' => 'Azerbaijani (Azerbaijan)',
- 'bs_BA' => 'Bosnian (Bosnia and Herzegovina)',
- 'bg_BG' => 'Bulgarian (Bulgaria)',
- 'ca_ES' => 'Catalan (Spain)',
- 'zh_CN' => 'Chinese (China)',
- 'zh_TW' => 'Chinese (Taiwan)',
- 'hr_HR' => 'Croatian (Croatia)',
- 'cs_CZ' => 'Czech (Czech Republic)',
- 'da_DK' => 'Danish (Denmark)',
- 'nl_NL' => 'Dutch (Netherlands)',
- 'en_GB' => 'English (United Kingdom)',
- 'en_US' => 'English (United States)',
- 'eo_XX' => 'Esperanto',
- 'et_EE' => 'Estonian (Estonia)',
- 'fo_FO' => 'Faroese (Faroe Islands)',
- 'fi_FI' => 'Finnish (Finland)',
- 'fr_FR' => 'French (France)',
- 'de_DE' => 'German (Germany)',
- 'el_GR' => 'Greek (Greece)',
- 'he_IL' => 'Hebrew (Israel)',
- 'hu_HU' => 'Hungarian (Hungary)',
- 'is_IS' => 'Icelandic (Iceland)',
- 'id_ID' => 'Indonesian (Indonesia)',
- 'it_IT' => 'Italian (Italy)',
- 'ja_JP' => 'Japanese (Japan)',
- 'km_KH' => 'Khmer (Cambodia)',
- 'lc_XX' => 'LOLCAT',
- 'lv_LV' => 'Latvian (Latvia)',
- 'lt_LT' => 'Lithuanian (Lithuania)',
- 'ms_MY' => 'Malay (Malaysia)',
- 'mi_NZ' => 'Maori (New Zealand)',
- 'ne_NP' => 'Nepali (Nepal)',
- 'nb_NO' => 'Norwegian',
- 'fa_IR' => 'Persian (Iran)',
- 'pl_PL' => 'Polish (Poland)',
- 'pt_BR' => 'Portuguese (Brazil)',
- 'pa_IN' => 'Punjabi (India)',
- 'ro_RO' => 'Romanian (Romania)',
- 'ru_RU' => 'Russian (Russia)',
- 'sr_RS' => 'Serbian (Serbia)',
- 'si_LK' => 'Sinhalese (Sri Lanka)',
- 'sk_SK' => 'Slovak (Slovakia)',
- 'sl_SI' => 'Slovenian (Slovenia)',
- 'es_AR' => 'Spanish (Argentina)',
- 'es_MX' => 'Spanish (Mexico)',
- 'es_ES' => 'Spanish (Spain)',
- 'sv_SE' => 'Swedish (Sweden)',
- 'th_TH' => 'Thai (Thailand)',
- 'tr_TR' => 'Turkish (Turkey)',
- 'uk_UA' => 'Ukrainian (Ukraine)',
- 'uz_UZ' => 'Uzbek (Uzbekistan)',
- 'vi_VN' => 'Vietnamese (Vietnam)',
-);
-
-// 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);
-}
-
-// Load database config
-if(isset($_REQUEST['db'])) {
- if(isset($_REQUEST['db']['type'])) {
- $type = $_REQUEST['db']['type'];
- } else {
- if ($type = getenv('SS_DATABASE_CLASS')) {
- $_REQUEST['db']['type'] = $type;
- } elseif( $databaseClasses['MySQLPDODatabase']['supported'] ) {
- $type = $_REQUEST['db']['type'] = 'MySQLPDODatabase';
- } elseif( $databaseClasses['MySQLDatabase']['supported'] ) {
- $type = $_REQUEST['db']['type'] = 'MySQLDatabase';
- } else {
- // handle error
- }
- }
-
- // Disabled inputs don't submit anything - we need to use the environment (except the database name)
- if($usingEnv) {
- $_REQUEST['db'][$type] = $databaseConfig = array(
- "type" => getenv('SS_DATABASE_CLASS') ?: $type,
- "server" => getenv('SS_DATABASE_SERVER') ?: "localhost",
- "username" => getenv('SS_DATABASE_USERNAME') ?: "root",
- "password" => getenv('SS_DATABASE_PASSWORD') ?: "",
- "database" => $_REQUEST['db'][$type]['database'],
- );
-
- } else {
- // Normal behaviour without the environment
- $databaseConfig = $_REQUEST['db'][$type];
- $databaseConfig['type'] = $type;
- }
-} else {
- if($type = getenv('SS_DATABASE_CLASS')) {
- $_REQUEST['db']['type'] = $type;
- } elseif( $databaseClasses['MySQLPDODatabase']['supported'] ) {
- $type = $_REQUEST['db']['type'] = 'MySQLPDODatabase';
- } elseif( $databaseClasses['MySQLDatabase']['supported'] ) {
- $type = $_REQUEST['db']['type'] = 'MySQLDatabase';
- } else {
- // handle error
- }
- $_REQUEST['db'][$type] = $databaseConfig = array(
- "type" => $type,
- "server" => getenv('SS_DATABASE_SERVER') ?: "localhost",
- "username" => getenv('SS_DATABASE_USERNAME') ?: "root",
- "password" => getenv('SS_DATABASE_PASSWORD') ?: "",
- "database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite",
- );
-}
-
-if(isset($_REQUEST['admin'])) {
- // Disabled inputs don't submit anything - we need to use the environment (except the database name)
- if($usingEnv) {
- $_REQUEST['admin'] = $adminConfig = array(
- 'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
- 'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
- );
- } else {
- $adminConfig = $_REQUEST['admin'];
- }
-} else {
- $_REQUEST['admin'] = $adminConfig = array(
- 'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
- 'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
- );
-}
-
-$alreadyInstalled = false;
-if(file_exists('mysite/_config.php')) {
- // Find the $database variable in the relevant config file without having to execute the config file
- if(preg_match("/\\\$database\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) {
- eval($parts[0]);
- if(!empty($database)) {
- $alreadyInstalled = true;
- }
- // Assume that if $databaseConfig is defined in mysite/_config.php, then a non-environment-based installation has
- // already gone ahead
- } else if(preg_match("/\\\$databaseConfig\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) {
- $alreadyInstalled = true;
- }
-}
-
-if(file_exists(FRAMEWORK_NAME . '/silverstripe_version')) {
- $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version');
-} else {
- $silverstripe_version = "unknown";
-}
-
-// Check requirements
-$req = new InstallRequirements();
-$req->check();
-
-$webserverConfigFile = '';
-if($req->isIIS()) {
- $webserverConfigFile = 'web.config';
-} else {
- $webserverConfigFile = '.htaccess';
-}
-
-if($req->hasErrors()) {
- $hasErrorOtherThanDatabase = true;
- $phpIniLocation = php_ini_loaded_file();
-}
-
-if($databaseConfig) {
- $dbReq = new InstallRequirements();
- $dbReq->checkDatabase($databaseConfig);
-}
-
-if($adminConfig) {
- $adminReq = new InstallRequirements();
- $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);
-}
-
-if((isset($_REQUEST['go']) || $installFromCli) && !$req->hasErrors() && !$dbReq->hasErrors() && $adminConfig['username'] && $adminConfig['password']) {
- // Confirm before reinstalling
- if(!$installFromCli && $alreadyInstalled) {
- include(__DIR__ . '/config-form.html');
-
- } else {
- $inst = new Installer();
- if($_REQUEST) $inst->install($_REQUEST);
- else $inst->install(array(
- 'db' => $databaseConfig,
- 'admin' => $adminConfig,
- ));
- }
-
-// Show the config form
-} else {
- include(__DIR__ . '/config-form.html');
-}
-
-/**
- * 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 {
- var $errors, $warnings, $tests;
-
- /**
- * 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;
-
- // Check if the server is available
- $usePath = !empty($databaseConfig['path']) && empty($databaseConfig['server']);
- if(!$this->requireDatabaseServer(
- $databaseConfig,
- array(
- "Database Configuration",
- "Database server",
- $usePath
- ? "I couldn't write to path '$databaseConfig[path]'"
- : "I couldn't find a database server on '$databaseConfig[server]'",
- $usePath ? $databaseConfig['path'] : $databaseConfig['server']
- )
- )) 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 if the web server is IIS and version greater than the given version.
- *
- * @param int $fromVersion
- * @return bool
- */
- public function isIIS($fromVersion = 7) {
- if(strpos($this->findWebserver(), 'IIS/') === false) {
- return false;
- }
- return substr(strstr($this->findWebserver(), '/'), -3, 1) >= $fromVersion;
- }
-
- public function isApache() {
- if(strpos($this->findWebserver(), 'Apache') !== false) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Find the webserver software running on the PHP host.
- * @return string|boolean 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));
- }
-
- /**
- * Check everything except the database
- */
- public function check() {
- $this->errors = null;
- $isApache = $this->isApache();
- $isIIS = $this->isIIS();
- $webserver = $this->findWebserver();
-
- $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(FRAMEWORK_NAME . '/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('mysite', array("File permissions", "mysite/ directory exists?"));
- $this->requireModule(FRAMEWORK_NAME, array("File permissions", FRAMEWORK_NAME . "/ directory exists?"));
-
- if($isApache) {
- $this->checkApacheVersion(array(
- "Webserver Configuration",
- "Webserver is not Apache 1.x", "SilverStripe requires Apache version 2 or greater",
- $webserver
- ));
- $this->requireWriteable('.htaccess', array("File permissions", "Is the .htaccess file writeable?", null));
- } elseif($isIIS) {
- $this->requireWriteable('web.config', array("File permissions", "Is the web.config file writeable?", null));
- }
-
- $this->requireWriteable('mysite/_config.php', array(
- "File permissions",
- "Is the mysite/_config.php file writeable?",
- null
- ));
-
- $this->requireWriteable('mysite/_config/config.yml', array(
- "File permissions",
- "Is the mysite/_config/config.yml file writeable?",
- null
- ));
-
- if(!$this->checkModuleExists('cms')) {
- $this->requireWriteable('mysite/code/RootURLController.php', array(
- "File permissions",
- "Is the mysite/code/RootURLController.php file writeable?",
- null
- ));
- }
- $this->requireWriteable('assets', array("File permissions", "Is the assets/ directory writeable?", null));
-
- try {
- $tempFolder = getTempFolder();
- } 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 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.',
- ini_get('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 &
- // which will results in links like ?param=value&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.",
- ini_get("memory_limit")
- ));
-
- return $this->errors;
- }
-
- 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.
- if($settingName == 'display_errors') {
- global $originalDisplayErrorsValue;
- $val = $originalDisplayErrorsValue;
- } else {
- $val = ini_get($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 = ini_get($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);
-
- $result = ini_get('date.timezone') && in_array(ini_get('date.timezone'), timezone_identifiers_list());
- if(!$result) {
- $this->error($testDetails);
- }
- }
-
- public function requireMemory($min, $recommended, $testDetails) {
- $_SESSION['forcemem'] = false;
-
- $mem = $this->getPHPMemory();
- if($mem < (64 * 1024 * 1024)) {
- ini_set('memory_limit', '64M');
- $mem = $this->getPHPMemory();
- $testDetails[3] = ini_get("memory_limit");
- }
-
- $this->testing($testDetails);
-
- if($mem < $min && $mem > 0) {
- $message = $testDetails[2] . " You only have " . ini_get("memory_limit") . " allocated";
- $this->error($testDetails, $message);
- return false;
- } else if($mem < $recommended && $mem > 0) {
- $message = $testDetails[2] . " You only have " . ini_get("memory_limit") . " 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 = ini_get("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 "The following problems are preventing me from installing SilverStripe CMS:
\n\n";
- foreach($this->errors as $error) {
- echo "" . htmlentities(implode(", ", $error), ENT_COMPAT, 'UTF-8') . "\n";
- }
- }
- }
-
- public function showTable($section = null) {
- if($section) {
- $tests = $this->tests[$section];
- $id = strtolower(str_replace(' ', '_', $section));
- echo "";
- foreach($tests as $test => $result) {
- echo "$test | "
- . nl2br(htmlentities($result[1], ENT_COMPAT, 'UTF-8')) . " |
";
- }
- echo "
";
-
- } 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 .= "$test | "
- . nl2br(htmlentities($result[1], ENT_COMPAT, 'UTF-8')) . " |
";
- }
- $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;
- } else if($warningRequirements > 0) {
- $className = "warning";
- $text = "All Requirements Pass but " . $warningRequirements . ' ' . $pluralWarnings;
- }
-
- echo "";
- echo "";
- echo $output;
- echo "
";
- }
- }
- }
-
- 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;
- }
-
- /**
- * Check that a module exists
- *
- * @param string $dirname
- * @return bool
- */
- public function checkModuleExists($dirname) {
- $path = $this->getBaseDir() . $dirname;
- return file_exists($path) && ($dirname == 'mysite' || file_exists($path . '/_config.php'));
- }
-
- /**
- * 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') && $dirname != 'mysite') {
- $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) {
- $this->testing($testDetails);
- $filename = $this->getBaseDir() . $filename;
- if(!file_exists($filename)) {
- $testDetails[2] .= " (file '$filename' not found)";
- $this->error($testDetails);
- }
- }
-
- public function requireWriteable($filename, $testDetails, $absolute = false) {
- $this->testing($testDetails);
-
- if($absolute) {
- $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
- } else {
- $filename = $this->getBaseDir() . str_replace('/', DIRECTORY_SEPARATOR, $filename);
- }
-
- if(file_exists($filename)) $isWriteable = is_writeable($filename);
- else $isWriteable = is_writeable(dirname($filename));
-
- if(!$isWriteable) {
- 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";
- }
-
- $this->error($testDetails);
- }
- }
-
- public function requireTempFolder($testDetails) {
- $this->testing($testDetails);
-
- try {
- $tempFolder = getTempFolder();
- } 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 testApacheRewriteExists($moduleName = 'mod_rewrite') {
- if(function_exists('apache_get_modules') && in_array($moduleName, apache_get_modules())) {
- return true;
- } elseif(isset($_SERVER['HTTP_MOD_REWRITE']) && $_SERVER['HTTP_MOD_REWRITE'] == 'On') {
- return true;
- } elseif(isset($_SERVER['REDIRECT_HTTP_MOD_REWRITE']) && $_SERVER['REDIRECT_HTTP_MOD_REWRITE'] == 'On') {
- return true;
- } else {
- return false;
- }
- }
-
- public function testIISRewriteModuleExists($moduleName = 'IIS_UrlRewriteModule') {
- if(isset($_SERVER[$moduleName]) && $_SERVER[$moduleName]) {
- return true;
- } else {
- return false;
- }
- }
-
- public function requireApacheRewriteModule($moduleName, $testDetails) {
- $this->testing($testDetails);
- if($this->testApacheRewriteExists()) {
- return true;
- } else {
- $this->warning($testDetails);
- return false;
- }
- }
-
- /**
- * Determines if the web server has any rewriting capability.
- * @return boolean
- */
- public function hasRewritingCapability() {
- return ($this->testApacheRewriteExists() || $this->testIISRewriteModuleExists());
- }
-
- public function requireIISRewriteModule($moduleName, $testDetails) {
- $this->testing($testDetails);
- if($this->testIISRewriteModuleExists()) {
- return true;
- } else {
- $this->warning($testDetails);
- return false;
- }
- }
-
- 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);
- }
-
- 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;
- }
- }
-
- // Must be PHP4 compatible
- var $baseDir;
-
- public function getBaseDir() {
- // Cache the value so that when the installer mucks with SCRIPT_FILENAME half way through, this method
- // still returns the correct value.
- if(!$this->baseDir) $this->baseDir = realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . DIRECTORY_SEPARATOR;
- return $this->baseDir;
- }
-
- 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);
- }
-
-}
-
-class Installer extends InstallRequirements {
- public function __construct() {
- // Cache the baseDir value
- $this->getBaseDir();
- }
-
- public function install($config) {
- ?>
-
-
-
- Installing SilverStripe...
-
-
-
-
-
-
-
-
-
-
-
-
Installing SilverStripe...
-
-
I am now running through the installation steps (this should take about 30 seconds)
-
-
If you receive a fatal error, refresh this page to continue the installation
-
-findWebserver();
- $isIIS = $this->isIIS();
- $isApache = $this->isApache();
-
- flush();
-
- if(isset($config['stats'])) {
- if(file_exists(FRAMEWORK_NAME . '/silverstripe_version')) {
- $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version');
- } else {
- $silverstripe_version = "unknown";
- }
-
- $phpVersion = urlencode(phpversion());
- $encWebserver = urlencode($webserver);
- $dbType = $config['db']['type'];
-
- // Try to determine the database version from the helper
- $databaseVersion = $config['db']['type'];
- $helper = $this->getDatabaseConfigurationHelper($dbType);
- if($helper && method_exists($helper, 'getDatabaseVersion')) {
- $versionConfig = $config['db'][$dbType];
- $versionConfig['type'] = $dbType;
- $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($versionConfig));
- }
-
- $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$encWebserver";
-
- if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
- $url .= '&ID=' . $_SESSION['StatsID'];
- }
-
- @$_SESSION['StatsID'] = file_get_contents($url);
- }
-
- if(file_exists('mysite/_config.php')) {
- // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly
- // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them
- $fh = fopen('mysite/_config.php', 'wb');
- fclose($fh);
- }
-
- // Escape user input for safe insertion into PHP file
- $theme = isset($_POST['template']) ? addcslashes($_POST['template'], "\'") : 'simple';
- $locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\'") : 'en_US';
- $type = addcslashes($config['db']['type'], "\'");
- $dbConfig = $config['db'][$type];
- foreach ($dbConfig as &$configValue) {
- $configValue = addcslashes($configValue, "\\\'");
- }
- if(!isset($dbConfig['path'])) $dbConfig['path'] = '';
- if(!$dbConfig) {
- echo "Bad config submitted
";
- print_r($config);
- echo "
";
- die();
- }
-
- // Write the config file
- global $usingEnv;
- if($usingEnv) {
- $this->statusMessage("Setting up 'mysite/_config.php' for use with environment variables...");
- $this->writeToFile("mysite/_config.php", <<
statusMessage("Setting up 'mysite/_config.php'...");
- // Create databaseConfig
- $lines = array(
- $lines[] = "\t'type' => '$type'"
- );
- foreach($dbConfig as $key => $value) {
- $lines[] = "\t'{$key}' => '$value'";
- }
- $databaseConfigContent = implode(",\n", $lines);
- $this->writeToFile("mysite/_config.php", <<statusMessage("Setting up 'mysite/_config/config.yml'");
- $this->writeToFile("mysite/_config/config.yml", <<checkModuleExists('cms')) {
- $this->writeToFile("mysite/code/RootURLController.php", <<Your site is now set up. Start adding controllers to mysite to get started.";
- }
-
-}
-PHP
- );
- }
-
- // Write the appropriate web server configuration file for rewriting support
- if($this->hasRewritingCapability()) {
- if($isApache) {
- $this->statusMessage("Setting up '.htaccess' file...");
- $this->createHtaccess();
- } elseif($isIIS) {
- $this->statusMessage("Setting up 'web.config' file...");
- $this->createWebConfig();
- }
- }
-
- // Load the SilverStripe runtime
- $_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/' . FRAMEWORK_NAME . '/main.php';
- chdir(FRAMEWORK_NAME);
-
- // Rebuild the manifest
- $_GET['flush'] = true;
- // Show errors as if you're in development mode
- $_SESSION['isDev'] = 1;
-
- $this->statusMessage("Building database schema...");
-
- require_once 'Core/Core.php';
-
- // Build database
- $request = new HTTPRequest('GET', '/');
- $request->setSession(new Session([]));
- $con = new Controller();
- $con->setRequest($request);
- $con->pushCurrent();
-
- global $databaseConfig;
- DB::connect($databaseConfig);
-
- $dbAdmin = new DatabaseAdmin();
- $dbAdmin->doInit();
-
- $dbAdmin->doBuild(true);
-
- // Create default administrator user and group in database
- // (not using Security::setDefaultAdmin())
- $adminMember = DefaultAdminService::singleton()->findOrCreateDefaultAdmin();
- $adminMember->Email = $config['admin']['username'];
- $adminMember->Password = $config['admin']['password'];
- $adminMember->PasswordEncryption = Security::config()->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())
- );
- }
-
- $_SESSION['username'] = $config['admin']['username'];
- $_SESSION['password'] = $config['admin']['password'];
-
- if(!$this->errors) {
- if(isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) {
- $this->statusMessage("Checking that friendly URLs work...");
- $this->checkRewrite();
- } else {
- require_once 'Core/Startup/ParameterConfirmationToken.php';
- $token = new ParameterConfirmationToken('flush');
- $params = http_build_query($token->params());
-
- $destinationURL = 'index.php/' .
- ($this->checkModuleExists('cms') ? "home/successfullyinstalled?$params" : "?$params");
-
- echo <<SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...
-
-
-HTML;
- }
- }
-
- return $this->errors;
- }
-
- public function writeToFile($filename, $content) {
- $base = $this->getBaseDir();
- $this->statusMessage("Setting up $base$filename");
-
- if((@$fh = fopen($base . $filename, 'wb')) && fwrite($fh, $content) && fclose($fh)) {
- return true;
- }
- $this->error("Couldn't write to file $base$filename");
- return false;
- }
-
- public function createHtaccess() {
- $start = "### SILVERSTRIPE START ###\n";
- $end = "\n### SILVERSTRIPE END ###";
-
- $base = dirname($_SERVER['SCRIPT_NAME']);
- if(defined('DIRECTORY_SEPARATOR')) $base = str_replace(DIRECTORY_SEPARATOR, '/', $base);
- else $base = str_replace("\\", '/', $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 = "";
- $modulePath = FRAMEWORK_NAME;
- $rewrite = <<
- Order deny,allow
- Deny from all
- Allow from 127.0.0.1
-
-
-# Deny access to IIS configuration
-
- Order deny,allow
- Deny from all
-
-
-# Deny access to YAML configuration files which might include sensitive information
-
- Order allow,deny
- Deny from all
-
-
-# Route errors to static pages automatically generated by SilverStripe
-ErrorDocument 404 /assets/error-404.html
-ErrorDocument 500 /assets/error-500.html
-
-
-
- # Turn off index.php handling requests to the homepage fixes issue in apache >=2.4
-
- DirectoryIndex disabled
-
-
- SetEnv HTTP_MOD_REWRITE On
- RewriteEngine On
- $baseClause
- $cgiClause
-
- # Deny access to potentially sensitive files and folders
- RewriteRule ^vendor(/|$) - [F,L,NC]
- RewriteRule silverstripe-cache(/|$) - [F,L,NC]
- RewriteRule composer\.(json|lock) - [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.
- RewriteCond %{REQUEST_URI} ^(.*)$
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteRule .* $modulePath/main.php?url=%1 [QSA]
-
-TEXT;
-
- if(file_exists('.htaccess')) {
- $htaccess = file_get_contents('.htaccess');
-
- 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('.htaccess', $start . $rewrite . $end);
- }
-
- /**
- * Writes basic configuration to the web.config for IIS
- * so that rewriting capability can be use.
- */
- public function createWebConfig() {
- $modulePath = FRAMEWORK_NAME;
- $content = <<
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-TEXT;
-
- $this->writeToFile('web.config', $content);
- }
-
- public function checkRewrite() {
- require_once 'Core/Startup/ParameterConfirmationToken.php';
- $token = new ParameterConfirmationToken('flush');
- $params = http_build_query($token->params());
-
- $destinationURL = str_replace('install.php', '', $_SERVER['SCRIPT_NAME']) .
- ($this->checkModuleExists('cms') ? "home/successfullyinstalled?$params" : "?$params");
-
- echo <<Testing...
-
-
-HTML;
- }
-
- public function var_export_array_nokeys($array) {
- $retval = "array(\n";
- foreach($array as $item) {
- $retval .= "\t'";
- $retval .= trim($item);
- $retval .= "',\n";
- }
- $retval .= ")";
- return $retval;
- }
-
- /**
- * Show an installation status message.
- * The output differs depending on whether this is CLI or web based
- *
- * @param string $msg
- */
- public function statusMessage($msg) {
- echo "$msg\n";
- flush();
- }
-}
diff --git a/src/Dev/Install/install5.php b/src/Dev/Install/install5.php
new file mode 100755
index 000000000..5694aa242
--- /dev/null
+++ b/src/Dev/Install/install5.php
@@ -0,0 +1,265 @@
+ 'Afrikaans (South Africa)',
+ 'ar_EG' => 'Arabic (Egypt)',
+ 'hy_AM' => 'Armenian (Armenia)',
+ 'ast_ES' => 'Asturian (Spain)',
+ 'az_AZ' => 'Azerbaijani (Azerbaijan)',
+ 'bs_BA' => 'Bosnian (Bosnia and Herzegovina)',
+ 'bg_BG' => 'Bulgarian (Bulgaria)',
+ 'ca_ES' => 'Catalan (Spain)',
+ 'zh_CN' => 'Chinese (China)',
+ 'zh_TW' => 'Chinese (Taiwan)',
+ 'hr_HR' => 'Croatian (Croatia)',
+ 'cs_CZ' => 'Czech (Czech Republic)',
+ 'da_DK' => 'Danish (Denmark)',
+ 'nl_NL' => 'Dutch (Netherlands)',
+ 'en_GB' => 'English (United Kingdom)',
+ 'en_US' => 'English (United States)',
+ 'eo_XX' => 'Esperanto',
+ 'et_EE' => 'Estonian (Estonia)',
+ 'fo_FO' => 'Faroese (Faroe Islands)',
+ 'fi_FI' => 'Finnish (Finland)',
+ 'fr_FR' => 'French (France)',
+ 'de_DE' => 'German (Germany)',
+ 'el_GR' => 'Greek (Greece)',
+ 'he_IL' => 'Hebrew (Israel)',
+ 'hu_HU' => 'Hungarian (Hungary)',
+ 'is_IS' => 'Icelandic (Iceland)',
+ 'id_ID' => 'Indonesian (Indonesia)',
+ 'it_IT' => 'Italian (Italy)',
+ 'ja_JP' => 'Japanese (Japan)',
+ 'km_KH' => 'Khmer (Cambodia)',
+ 'lc_XX' => 'LOLCAT',
+ 'lv_LV' => 'Latvian (Latvia)',
+ 'lt_LT' => 'Lithuanian (Lithuania)',
+ 'ms_MY' => 'Malay (Malaysia)',
+ 'mi_NZ' => 'Maori (New Zealand)',
+ 'ne_NP' => 'Nepali (Nepal)',
+ 'nb_NO' => 'Norwegian',
+ 'fa_IR' => 'Persian (Iran)',
+ 'pl_PL' => 'Polish (Poland)',
+ 'pt_BR' => 'Portuguese (Brazil)',
+ 'pa_IN' => 'Punjabi (India)',
+ 'ro_RO' => 'Romanian (Romania)',
+ 'ru_RU' => 'Russian (Russia)',
+ 'sr_RS' => 'Serbian (Serbia)',
+ 'si_LK' => 'Sinhalese (Sri Lanka)',
+ 'sk_SK' => 'Slovak (Slovakia)',
+ 'sl_SI' => 'Slovenian (Slovenia)',
+ 'es_AR' => 'Spanish (Argentina)',
+ 'es_MX' => 'Spanish (Mexico)',
+ 'es_ES' => 'Spanish (Spain)',
+ 'sv_SE' => 'Swedish (Sweden)',
+ 'th_TH' => 'Thai (Thailand)',
+ 'tr_TR' => 'Turkish (Turkey)',
+ 'uk_UA' => 'Ukrainian (Ukraine)',
+ 'uz_UZ' => 'Uzbek (Uzbekistan)',
+ 'vi_VN' => 'Vietnamese (Vietnam)',
+);
+
+// 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);
+}
+
+// Load database config
+if (isset($_REQUEST['db'])) {
+ if (isset($_REQUEST['db']['type'])) {
+ $type = $_REQUEST['db']['type'];
+ } else {
+ if ($type = getenv('SS_DATABASE_CLASS')) {
+ $_REQUEST['db']['type'] = $type;
+ } elseif ($databaseClasses['MySQLPDODatabase']['supported']) {
+ $type = $_REQUEST['db']['type'] = 'MySQLPDODatabase';
+ } elseif ($databaseClasses['MySQLDatabase']['supported']) {
+ $type = $_REQUEST['db']['type'] = 'MySQLDatabase';
+ } else {
+ // handle error
+ }
+ }
+
+ // Disabled inputs don't submit anything - we need to use the environment (except the database name)
+ if ($usingEnv) {
+ $_REQUEST['db'][$type] = $databaseConfig = array(
+ "type" => getenv('SS_DATABASE_CLASS') ?: $type,
+ "server" => getenv('SS_DATABASE_SERVER') ?: "localhost",
+ "username" => getenv('SS_DATABASE_USERNAME') ?: "root",
+ "password" => getenv('SS_DATABASE_PASSWORD') ?: "",
+ "database" => $_REQUEST['db'][$type]['database'],
+ );
+ } else {
+ // Normal behaviour without the environment
+ $databaseConfig = $_REQUEST['db'][$type];
+ $databaseConfig['type'] = $type;
+ }
+} else {
+ if ($type = getenv('SS_DATABASE_CLASS')) {
+ $_REQUEST['db']['type'] = $type;
+ } elseif ($databaseClasses['MySQLPDODatabase']['supported']) {
+ $type = $_REQUEST['db']['type'] = 'MySQLPDODatabase';
+ } elseif ($databaseClasses['MySQLDatabase']['supported']) {
+ $type = $_REQUEST['db']['type'] = 'MySQLDatabase';
+ } else {
+ // handle error
+ }
+ $_REQUEST['db'][$type] = $databaseConfig = array(
+ "type" => $type,
+ "server" => getenv('SS_DATABASE_SERVER') ?: "localhost",
+ "username" => getenv('SS_DATABASE_USERNAME') ?: "root",
+ "password" => getenv('SS_DATABASE_PASSWORD') ?: "",
+ "database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite",
+ );
+}
+
+if (isset($_REQUEST['admin'])) {
+ // Disabled inputs don't submit anything - we need to use the environment (except the database name)
+ if ($usingEnv) {
+ $_REQUEST['admin'] = $adminConfig = array(
+ 'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
+ 'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
+ );
+ } else {
+ $adminConfig = $_REQUEST['admin'];
+ }
+} else {
+ $_REQUEST['admin'] = $adminConfig = array(
+ 'username' => getenv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
+ 'password' => getenv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
+ );
+}
+
+$alreadyInstalled = false;
+if (file_exists('mysite/_config.php')) {
+ // Find the $database variable in the relevant config file without having to execute the config file
+ if (preg_match("/\\\$database\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) {
+ eval($parts[0]);
+ if (!empty($database)) {
+ $alreadyInstalled = true;
+ }
+ // Assume that if $databaseConfig is defined in mysite/_config.php, then a non-environment-based installation has
+ // already gone ahead
+ } elseif (preg_match(
+ "/\\\$databaseConfig\s*=\s*[^\n\r]+[\n\r]/",
+ file_get_contents("mysite/_config.php"),
+ $parts
+ )) {
+ $alreadyInstalled = true;
+ }
+}
+
+if (file_exists(FRAMEWORK_NAME . '/silverstripe_version')) {
+ $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version');
+} else {
+ $silverstripe_version = "unknown";
+}
+
+// Check requirements
+$req = new InstallRequirements();
+$req->check();
+
+$webserverConfigFile = '';
+if ($req->isIIS()) {
+ $webserverConfigFile = 'web.config';
+} else {
+ $webserverConfigFile = '.htaccess';
+}
+
+if ($req->hasErrors()) {
+ $hasErrorOtherThanDatabase = true;
+ $phpIniLocation = php_ini_loaded_file();
+}
+
+$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);
+}
+
+if ((isset($_REQUEST['go']) || $installFromCli)
+ && !$req->hasErrors()
+ && !$dbReq->hasErrors()
+ && $adminConfig['username']
+ && $adminConfig['password']
+) {
+ // Confirm before reinstalling
+ if (!$installFromCli && $alreadyInstalled) {
+ include(__DIR__ . '/config-form.html');
+ } else {
+ $inst = new Installer();
+ if ($_REQUEST) {
+ $inst->install($_REQUEST);
+ } else {
+ $inst->install(array(
+ 'db' => $databaseConfig,
+ 'admin' => $adminConfig,
+ ));
+ }
+ }
+
+// Show the config form
+} else {
+ include(__DIR__ . '/config-form.html');
+}
+
diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php
index 6a0dd94cb..dd80b2210 100644
--- a/src/Dev/SapphireTest.php
+++ b/src/Dev/SapphireTest.php
@@ -894,7 +894,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
$request->setSession($session);
// Test application
- $kernel = new TestKernel();
+ $kernel = new TestKernel(BASE_PATH);
$app = new HTTPApplication($kernel);
// Custom application
diff --git a/src/Dev/State/GlobalsTestState.php b/src/Dev/State/GlobalsTestState.php
index df94e7842..a29b139aa 100644
--- a/src/Dev/State/GlobalsTestState.php
+++ b/src/Dev/State/GlobalsTestState.php
@@ -3,6 +3,7 @@
namespace SilverStripe\Dev\State;
use SilverStripe\Control\Director;
+use SilverStripe\Core\Environment;
use SilverStripe\Dev\SapphireTest;
/**
@@ -24,21 +25,21 @@ class GlobalsTestState implements TestState
public function setUp(SapphireTest $test)
{
- $this->vars = Director::envToVars();
+ $this->vars = Environment::getVariables();
}
public function tearDown(SapphireTest $test)
{
- Director::varsToEnv($this->vars);
+ Environment::setVariables($this->vars);
}
public function setUpOnce($class)
{
- $this->staticVars = Director::envToVars();
+ $this->staticVars = Environment::getVariables();
}
public function tearDownOnce($class)
{
- Director::varsToEnv($this->staticVars);
+ Environment::setVariables($this->staticVars);
}
}
diff --git a/src/ORM/DatabaseAdmin.php b/src/ORM/DatabaseAdmin.php
index 0419378e2..efb09fd70 100644
--- a/src/ORM/DatabaseAdmin.php
+++ b/src/ORM/DatabaseAdmin.php
@@ -122,7 +122,7 @@ class DatabaseAdmin extends Controller
increase_time_limit_to(600);
// Get all our classes
- ClassLoader::inst()->getManifest()->regenerate();
+ ClassLoader::inst()->getManifest()->regenerate(false);
$url = $this->getReturnURL();
if ($url) {
diff --git a/src/includes/cli.php b/src/includes/cli.php
deleted file mode 100644
index 2b24f78b8..000000000
--- a/src/includes/cli.php
+++ /dev/null
@@ -1,64 +0,0 @@
- 'HTTP/1.1',
- 'HTTP_ACCEPT' => 'text/plain;q=0.5',
- 'HTTP_ACCEPT_LANGUAGE' => '*;q=0.5',
- 'HTTP_ACCEPT_ENCODING' => '',
- 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1;q=0.5',
- 'SERVER_SIGNATURE' => 'Command-line PHP/' . phpversion(),
- 'SERVER_SOFTWARE' => 'PHP/' . phpversion(),
- 'SERVER_ADDR' => '127.0.0.1',
- 'REMOTE_ADDR' => '127.0.0.1',
- 'REQUEST_METHOD' => 'GET',
- 'HTTP_USER_AGENT' => 'CLI',
-), $_SERVER);
-
-/**
- * Process arguments and load them into the $_GET and $_REQUEST arrays
- * For example,
- * sake my/url somearg otherarg key=val --otherkey=val third=val&fourth=val
- *
- * Will result in the following get data:
- * args => array('somearg', 'otherarg'),
- * key => val
- * otherkey => val
- * third => val
- * fourth => val
- */
-if (isset($_SERVER['argv'][2])) {
- call_user_func(function () {
- $args = array_slice($_SERVER['argv'], 2);
- if (!isset($_GET)) {
- $_GET = array();
- }
- if (!isset($_REQUEST)) {
- $_REQUEST = array();
- }
- foreach ($args as $arg) {
- if (strpos($arg, '=') == false) {
- $_GET['args'][] = $arg;
- } else {
- $newItems = array();
- parse_str((substr($arg, 0, 2) == '--') ? substr($arg, 2) : $arg, $newItems);
- $_GET = array_merge($_GET, $newItems);
- }
- }
- $_REQUEST = array_merge($_REQUEST, $_GET);
- });
-}
-
-// Set 'url' GET parameter
-if (isset($_SERVER['argv'][1])) {
- $_REQUEST['url'] = $_SERVER['argv'][1];
- $_GET['url'] = $_SERVER['argv'][1];
-}
diff --git a/src/includes/constants.php b/src/includes/constants.php
index 62042f915..2eee0dacc 100644
--- a/src/includes/constants.php
+++ b/src/includes/constants.php
@@ -3,6 +3,7 @@
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use SilverStripe\Control\Util\IPUtils;
+use SilverStripe\Core\TempFolder;
/**
* This file is the Framework constants bootstrap. It will prepare some basic common constants.
@@ -148,5 +149,5 @@ if (defined('CUSTOM_INCLUDE_PATH')) {
// Define the temporary folder if it wasn't defined yet
if (!defined('TEMP_FOLDER')) {
- define('TEMP_FOLDER', getTempFolder(BASE_PATH));
+ define('TEMP_FOLDER', TempFolder::getTempFolder(BASE_PATH));
}
diff --git a/src/includes/functions.php b/src/includes/functions.php
index 2411f3073..83f1a61d4 100644
--- a/src/includes/functions.php
+++ b/src/includes/functions.php
@@ -62,258 +62,3 @@ function _t($entity, $arg = null)
// Pass args directly to handle deprecation
return call_user_func_array([i18n::class, '_t'], func_get_args());
}
-
-/**
- * Increase the memory limit to the given level if it's currently too low.
- * Only increases up to the maximum defined in {@link set_increase_memory_limit_max()},
- * and defaults to the 'memory_limit' setting in the PHP configuration.
- *
- * @param string|int $memoryLimit A memory limit string, such as "64M". If omitted, unlimited memory will be set.
- * @return Boolean TRUE indicates a successful change, FALSE a denied change.
- */
-function increase_memory_limit_to($memoryLimit = -1)
-{
- $curLimit = ini_get('memory_limit');
-
- // Can't go higher than infinite
- if ($curLimit == -1) {
- return true;
- }
-
- // Check hard maximums
- $max = get_increase_memory_limit_max();
-
- if ($max && $max != -1 && translate_memstring($memoryLimit) > translate_memstring($max)) {
- return false;
- }
-
- // Increase the memory limit if it's too low
- if ($memoryLimit == -1 || translate_memstring($memoryLimit) > translate_memstring($curLimit)) {
- ini_set('memory_limit', $memoryLimit);
- }
-
- return true;
-}
-
-$_increase_memory_limit_max = ini_get('memory_limit');
-
-/**
- * Set the maximum allowed value for {@link increase_memory_limit_to()}.
- * The same result can also be achieved through 'suhosin.memory_limit'
- * if PHP is running with the Suhosin system.
- *
- * @param string $memoryLimit Memory limit string
- */
-function set_increase_memory_limit_max($memoryLimit)
-{
- global $_increase_memory_limit_max;
- $_increase_memory_limit_max = $memoryLimit;
-}
-
-/**
- * @return string Memory limit string
- */
-function get_increase_memory_limit_max()
-{
- global $_increase_memory_limit_max;
- return $_increase_memory_limit_max;
-}
-
-/**
- * Increases the XDebug parameter max_nesting_level, which limits how deep recursion can go.
- * Only does anything if (a) xdebug is installed and (b) the new limit is higher than the existing limit
- *
- * @param int $limit - The new limit to increase to
- */
-function increase_xdebug_nesting_level_to($limit)
-{
- if (function_exists('xdebug_enable')) {
- $current = ini_get('xdebug.max_nesting_level');
- if ((int)$current < $limit) {
- ini_set('xdebug.max_nesting_level', $limit);
- }
- }
-}
-
-/**
- * Turn a memory string, such as 512M into an actual number of bytes.
- *
- * @param string $memString A memory limit string, such as "64M"
- * @return float
- */
-function translate_memstring($memString)
-{
- 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);
- }
-}
-
-/**
- * Increase the time limit of this script. By default, the time will be unlimited.
- * Only works if 'safe_mode' is off in the PHP configuration.
- * Only values up to {@link get_increase_time_limit_max()} are allowed.
- *
- * @param int $timeLimit The time limit in seconds. If omitted, no time limit will be set.
- * @return Boolean TRUE indicates a successful change, FALSE a denied change.
- */
-function increase_time_limit_to($timeLimit = null)
-{
- $max = get_increase_time_limit_max();
- if ($max != -1 && $max != null && $timeLimit > $max) {
- return false;
- }
-
- if (!ini_get('safe_mode')) {
- if (!$timeLimit) {
- set_time_limit(0);
- return true;
- } else {
- $currTimeLimit = ini_get('max_execution_time');
- // Only increase if its smaller
- if ($currTimeLimit && $currTimeLimit < $timeLimit) {
- set_time_limit($timeLimit);
- }
- return true;
- }
- } else {
- return false;
- }
-}
-
-/**
- * Set the maximum allowed value for {@link increase_timeLimit_to()};
- *
- * @param int $timeLimit Limit in seconds
- */
-function set_increase_time_limit_max($timeLimit)
-{
- global $_increase_time_limit_max;
- $_increase_time_limit_max = $timeLimit;
-}
-
-/**
- * @return Int Limit in seconds
- */
-function get_increase_time_limit_max()
-{
- global $_increase_time_limit_max;
- return $_increase_time_limit_max;
-}
-
-
-/**
- * Returns the temporary folder path that silverstripe should use for its cache files.
- *
- * @param string $base The base path to use for determining the temporary path
- * @return string Path to temp
- */
-function getTempFolder($base = null)
-{
- $parent = getTempParentFolder($base);
-
- // The actual temp folder is a subfolder of getTempParentFolder(), named by username
- $subfolder = $parent . DIRECTORY_SEPARATOR . getTempFolderUsername();
-
- if (!@file_exists($subfolder)) {
- mkdir($subfolder);
- }
-
- return $subfolder;
-}
-
-/**
- * Returns as best a representation of the current username as we can glean.
- *
- * @return string
- */
-function getTempFolderUsername()
-{
- $user = getenv('APACHE_RUN_USER');
- if (!$user) {
- $user = getenv('USER');
- }
- if (!$user) {
- $user = getenv('USERNAME');
- }
- if (!$user && function_exists('posix_getpwuid') && function_exists('posix_getuid')) {
- $userDetails = posix_getpwuid(posix_getuid());
- $user = $userDetails['name'];
- }
- if (!$user) {
- $user = 'unknown';
- }
- $user = preg_replace('/[^A-Za-z0-9_\-]/', '', $user);
- return $user;
-}
-
-/**
- * Return the parent folder of the temp folder.
- * The temp folder will be a subfolder of this, named by username.
- * This structure prevents permission problems.
- *
- * @param string $base
- * @return string
- * @throws Exception
- */
-function getTempParentFolder($base = null)
-{
- if (!$base && defined('BASE_PATH')) {
- $base = BASE_PATH;
- }
-
- // first, try finding a silverstripe-cache dir built off the base path
- $tempPath = $base . DIRECTORY_SEPARATOR . 'silverstripe-cache';
- if (@file_exists($tempPath)) {
- if ((fileperms($tempPath) & 0777) != 0777) {
- @chmod($tempPath, 0777);
- }
- return $tempPath;
- }
-
- // failing the above, try finding a namespaced silverstripe-cache dir in the system temp
- $tempPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR .
- 'silverstripe-cache-php' . preg_replace('/[^\w-\.+]+/', '-', PHP_VERSION) .
- str_replace(array(' ', '/', ':', '\\'), '-', $base);
- if (!@file_exists($tempPath)) {
- $oldUMask = umask(0);
- @mkdir($tempPath, 0777);
- umask($oldUMask);
-
- // if the folder already exists, correct perms
- } else {
- if ((fileperms($tempPath) & 0777) != 0777) {
- @chmod($tempPath, 0777);
- }
- }
-
- $worked = @file_exists($tempPath) && @is_writable($tempPath);
-
- // failing to use the system path, attempt to create a local silverstripe-cache dir
- if (!$worked) {
- $tempPath = $base . DIRECTORY_SEPARATOR . 'silverstripe-cache';
- if (!@file_exists($tempPath)) {
- $oldUMask = umask(0);
- @mkdir($tempPath, 0777);
- umask($oldUMask);
- }
-
- $worked = @file_exists($tempPath) && @is_writable($tempPath);
- }
-
- if (!$worked) {
- throw new Exception(
- 'Permission problem gaining access to a temp folder. ' .
- 'Please create a folder named silverstripe-cache in the base folder ' .
- 'of the installation and ensure it has the correct permissions'
- );
- }
-
- return $tempPath;
-}
diff --git a/tests/php/Core/MemoryLimitTest.php b/tests/php/Core/MemoryLimitTest.php
index f5717fd58..b144b0335 100644
--- a/tests/php/Core/MemoryLimitTest.php
+++ b/tests/php/Core/MemoryLimitTest.php
@@ -2,35 +2,64 @@
namespace SilverStripe\Core\Tests;
+use SilverStripe\Core\Environment;
use SilverStripe\Dev\SapphireTest;
class MemoryLimitTest extends SapphireTest
{
+ protected $origMemLimitMax;
+ protected $origTimeLimitMax;
+ protected $origMemLimit;
+ protected $origTimeLimit;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ // see http://www.hardened-php.net/suhosin/configuration.html#suhosin.memory_limit
+ if (in_array('suhosin', get_loaded_extensions())) {
+ $this->markTestSkipped("This test cannot be run with suhosin installed");
+ } else {
+ $this->origMemLimit = ini_get('memory_limit');
+ $this->origTimeLimit = ini_get('max_execution_time');
+ $this->origMemLimitMax = Environment::getMemoryLimitMax();
+ $this->origTimeLimitMax = Environment::getTimeLimitMax();
+ Environment::setMemoryLimitMax(null);
+ Environment::setTimeLimitMax(null);
+ }
+ }
+
+ protected function tearDown()
+ {
+ if (!in_array('suhosin', get_loaded_extensions())) {
+ ini_set('memory_limit', $this->origMemLimit);
+ set_time_limit($this->origTimeLimit);
+ Environment::setMemoryLimitMax($this->origMemLimitMax);
+ Environment::setTimeLimitMax($this->origTimeLimitMax);
+ }
+ parent::tearDown();
+ }
public function testIncreaseMemoryLimitTo()
{
- if (!$this->canChangeMemory()) {
- return;
- }
-
ini_set('memory_limit', '64M');
// It can go up
- increase_memory_limit_to('128M');
+ Environment::increaseMemoryLimitTo('128M');
$this->assertEquals('128M', ini_get('memory_limit'));
// But not down
- increase_memory_limit_to('64M');
+ Environment::increaseMemoryLimitTo('64M');
$this->assertEquals('128M', ini_get('memory_limit'));
// Test the different kinds of syntaxes
- increase_memory_limit_to(1024*1024*200);
+ Environment::increaseMemoryLimitTo(1024*1024*200);
$this->assertEquals(1024*1024*200, ini_get('memory_limit'));
- increase_memory_limit_to('409600K');
+ Environment::increaseMemoryLimitTo('409600K');
$this->assertEquals('409600K', ini_get('memory_limit'));
- increase_memory_limit_to('1G');
+ Environment::increaseMemoryLimitTo('1G');
// If memory limit was left at 409600K, that means that the current testbox doesn't have
// 1G of memory available. That's okay; let's not report a failure for that.
@@ -39,80 +68,31 @@ class MemoryLimitTest extends SapphireTest
}
// No argument means unlimited
- increase_memory_limit_to();
+ Environment::increaseMemoryLimitTo();
$this->assertEquals(-1, ini_get('memory_limit'));
}
public function testIncreaseTimeLimitTo()
{
- if (!$this->canChangeMemory()) {
- return;
- }
-
// Can't change time limit
if (!set_time_limit(6000)) {
- return;
+ $this->markTestSkipped("Cannot change time limit");
}
// It can go up
- $this->assertTrue(increase_time_limit_to(7000));
+ $this->assertTrue(Environment::increaseTimeLimitTo(7000));
$this->assertEquals(7000, ini_get('max_execution_time'));
// But not down
- $this->assertTrue(increase_time_limit_to(5000));
+ $this->assertTrue(Environment::increaseTimeLimitTo(5000));
$this->assertEquals(7000, ini_get('max_execution_time'));
// 0/nothing means infinity
- $this->assertTrue(increase_time_limit_to());
+ $this->assertTrue(Environment::increaseTimeLimitTo());
$this->assertEquals(0, ini_get('max_execution_time'));
// Can't go down from there
- $this->assertTrue(increase_time_limit_to(10000));
+ $this->assertTrue(Environment::increaseTimeLimitTo(10000));
$this->assertEquals(0, ini_get('max_execution_time'));
}
-
-
- ///////////////////
-
- private $origMemLimit, $origTimeLimit;
-
- protected function setUp()
- {
- $this->origMemLimit = ini_get('memory_limit');
- $this->origTimeLimit = ini_get('max_execution_time');
- $this->origMemLimitMax = get_increase_memory_limit_max();
- $this->origTimeLimitMax = get_increase_time_limit_max();
- set_increase_memory_limit_max(-1);
- set_increase_time_limit_max(-1);
- }
-
- protected function tearDown()
- {
- ini_set('memory_limit', $this->origMemLimit);
- set_time_limit($this->origTimeLimit);
- set_increase_memory_limit_max($this->origMemLimitMax);
- set_increase_time_limit_max($this->origTimeLimitMax);
- }
-
- /**
- * Determines wether the environment generally allows
- * to change the memory limits, which is not always the case.
- *
- * @return Boolean
- */
- protected function canChangeMemory()
- {
- $exts = get_loaded_extensions();
- // see http://www.hardened-php.net/suhosin/configuration.html#suhosin.memory_limit
- if (in_array('suhosin', $exts)) {
- return false;
- }
-
- // We can't change memory limit in safe mode
- if (ini_get('safe_mode')) {
- return false;
- }
-
- return true;
- }
}