$details) {
$bits = explode('_', $code);
if(preg_match("/{$bits[0]}.{$bits[1]}/", $_SERVER['HTTP_USER_AGENT'])) {
$defaultLocale = $code;
break;
}
}
}
// Discover which databases are available
DatabaseAdapterRegistry::autodiscover();
// Determine which external database modules are USABLE
foreach(DatabaseAdapterRegistry::get_adapters() as $class => $details) {
$databaseClasses[$class] = $details;
if(file_exists($details['helperPath'])) {
$databaseClasses[$class]['hasModule'] = true;
include_once($details['helperPath']);
} else {
$databaseClasses[$class]['hasModule'] = false;
}
}
// Load database config
if(isset($_REQUEST['db'])) {
if(isset($_REQUEST['db']['type'])) $type = $_REQUEST['db']['type'];
else $type = $_REQUEST['db']['type'] = defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase';
// Disabled inputs don't submit anything - we need to use the environment (except the database name)
if($usingEnv) {
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : $type,
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "",
"database" => $_REQUEST['db'][$type]['database'],
);
} else {
// Normal behaviour without the environment
$databaseConfig = $_REQUEST['db'][$type];
$databaseConfig['type'] = $type;
}
} else {
$type = $_REQUEST['db']['type'] = defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase';
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => $type,
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? 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' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin',
'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? SS_DEFAULT_ADMIN_PASSWORD : '',
);
} else {
$adminConfig = $_REQUEST['admin'];
}
} else {
$_REQUEST['admin'] = $adminConfig = array(
'username' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin',
'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? 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($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(FRAMEWORK_NAME . '/dev/install/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(FRAMEWORK_NAME . '/dev/install/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.
*/
function checkDatabase($databaseConfig) {
if($this->requireDatabaseFunctions(
$databaseConfig,
array(
"Database Configuration",
"Database support",
"Database support in PHP",
$this->getDatabaseTypeNice($databaseConfig['type'])
)
)) {
if($this->requireDatabaseServer(
$databaseConfig,
array(
"Database Configuration",
"Database server",
$databaseConfig['type'] == 'SQLiteDatabase' ? "I couldn't write to path '$databaseConfig[path]'" : "I couldn't find a database server on '$databaseConfig[server]'",
$databaseConfig['type'] == 'SQLiteDatabase' ? $databaseConfig['path'] : $databaseConfig['server']
)
)) {
if($this->requireDatabaseConnection(
$databaseConfig,
array(
"Database Configuration",
"Database access credentials correct",
"That username/password doesn't work"
)
)) {
if($this->requireDatabaseVersion(
$databaseConfig,
array(
"Database Configuration",
"Database server meets required version",
'',
'Version ' . $this->getDatabaseConfigurationHelper($databaseConfig['type'])->getDatabaseVersion($databaseConfig)
)
)) {
$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"
)
);
}
}
}
}
}
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.
* @return boolean
*/
function isIIS($version = 7) {
if(strpos($this->findWebserver(), 'IIS/' . $version) !== false) {
return true;
} else {
return false;
}
}
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
*/
function findWebserver() {
// Try finding from SERVER_SIGNATURE or SERVER_SOFTWARE
$webserver = @$_SERVER['SERVER_SIGNATURE'];
if(!$webserver) $webserver = @$_SERVER['SERVER_SOFTWARE'];
if($webserver) return strip_tags(trim($webserver));
else return false;
}
/**
* Check everything except the database
*/
function check() {
$this->errors = null;
$isApache = $this->isApache();
$isIIS = $this->isIIS(7);
$webserver = $this->findWebserver();
$this->requirePHPVersion('5.3.10', '5.3.2', array("PHP Configuration", "PHP5 installed", null, "PHP version " . phpversion()));
// Check that we can identify the root folder successfully
$this->requireFile(FRAMEWORK_NAME . '/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->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));
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));
$tempFolder = $this->getTempFolder();
$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 config", "Recognised webserver", "You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."));
// 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."));
// Check for token_get_all
$this->requireFunction('token_get_all', array("PHP Configuration", "PHP Tokenizer", "PHP tokenizer 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 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 set and valid', 'date.timezone option in php.ini must be set correctly.', ini_get('date.timezone')));
$this->suggestPHPSetting('asp_tags', array(false,0,''), array('PHP Configuration', 'asp_tags option turned off', 'This should be turned off as it can cause issues with SilverStripe'));
$this->suggestPHPSetting('magic_quotes_gpc', array(false,0,''), array('PHP Configuration', 'magic_quotes_gpc option turned off', '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,0,''), array('PHP Configuration', 'display_errors option turned off', 'Unless you\'re in a development environment, this should be turned off, as it can expose sensitive data to website users.'));
// Check memory allocation
$this->requireMemory(32*1024*1024, 64*1024*1024, array("PHP Configuration", "Memory allocated (PHP config option 'memory_limit')", "SilverStripe needs a minimum of 32M allocated to PHP, but recommends 64M.", ini_get("memory_limit")));
return $this->errors;
}
function suggestPHPSetting($settingName, $settingValues, $testDetails) {
$this->testing($testDetails);
$val = ini_get($settingName);
if(!in_array($val, $settingValues) && $val != $settingValues) {
$testDetails[2] = "$settingName is set to '$val' in php.ini. $testDetails[2]";
$this->warning($testDetails);
}
}
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);
}
}
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) {
$testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
$this->error($testDetails);
} else if($mem < $recommended && $mem > 0) {
$testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
$this->warning($testDetails);
} elseif($mem == 0) {
$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);
}
}
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);
}
}
function listErrors() {
if($this->errors) {
echo "
The following problems are preventing me from installing SilverStripe CMS: