MINOR Convert crlf (Windows) line endings to lf (UNIX) for install.php (from r93895)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/phpinstaller/trunk@112087 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
sminnee 2010-10-13 02:26:57 +00:00
parent eebff68f46
commit e013e7512b

View File

@ -1,1141 +1,1141 @@
<?php <?php
/************************************************************************************ /************************************************************************************
************************************************************************************ ************************************************************************************
** ** ** **
** If you can read this text in your browser then you don't have PHP installed. ** ** If you can read this text in your browser then you don't have PHP installed. **
** Please install PHP 5.0 or higher, preferably PHP 5.2. ** ** Please install PHP 5.0 or higher, preferably PHP 5.2. **
** ** ** **
************************************************************************************ ************************************************************************************
************************************************************************************/ ************************************************************************************/
/** /**
* SilverStripe CMS Installer * SilverStripe CMS Installer
* This installer doesn't use any of the fancy Sapphire stuff in case it's unsupported. * This installer doesn't use any of the fancy Sapphire stuff in case it's unsupported.
* It's also PHP4 syntax compatable * It's also PHP4 syntax compatable
*/ */
// speed up mysql_connect timeout if the server can't be found // speed up mysql_connect timeout if the server can't be found
ini_set('mysql.connect_timeout', 5); ini_set('mysql.connect_timeout', 5);
ini_set('max_execution_time', 0); ini_set('max_execution_time', 0);
error_reporting(E_ALL ^ E_NOTICE); error_reporting(E_ALL ^ E_NOTICE);
session_start(); session_start();
$majorVersion = strtok(phpversion(),'.'); $majorVersion = strtok(phpversion(),'.');
if($majorVersion < 5) { if($majorVersion < 5) {
header("HTTP/1.1 500 Server Error"); header("HTTP/1.1 500 Server Error");
echo str_replace('$PHPVersion', phpversion(), file_get_contents("sapphire/dev/install/php5-required.html")); echo str_replace('$PHPVersion', phpversion(), file_get_contents("sapphire/dev/install/php5-required.html"));
die(); die();
} }
// Include environment files // Include environment files
$usingEnv = false; $usingEnv = false;
$envFiles = array('_ss_environment.php', '../_ss_environment.php', '../../_ss_environment.php'); $envFiles = array('_ss_environment.php', '../_ss_environment.php', '../../_ss_environment.php');
foreach($envFiles as $envFile) { foreach($envFiles as $envFile) {
if(@file_exists($envFile)) { if(@file_exists($envFile)) {
include_once($envFile); include_once($envFile);
$usingEnv = true; $usingEnv = true;
break; break;
} }
} }
// Load database config // Load database config
if(isset($_REQUEST['mysql'])) { if(isset($_REQUEST['mysql'])) {
$databaseConfig = $_REQUEST['mysql']; $databaseConfig = $_REQUEST['mysql'];
} else { } else {
$_REQUEST['mysql'] = $databaseConfig = array( $_REQUEST['mysql'] = $databaseConfig = array(
"type" => "MySQLDatabase", "type" => "MySQLDatabase",
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost", "server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root", "username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "", "password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "",
"database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite", "database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite",
); );
} }
if(isset($_REQUEST['admin'])) { if(isset($_REQUEST['admin'])) {
$adminConfig = $_REQUEST['admin']; $adminConfig = $_REQUEST['admin'];
} else { } else {
$_REQUEST['admin'] = $adminConfig = array( $_REQUEST['admin'] = $adminConfig = array(
'username' => 'admin', 'username' => 'admin',
'password' => '', 'password' => '',
'firstname' => '', 'firstname' => '',
'surname' => '' 'surname' => ''
); );
} }
$alreadyInstalled = false; $alreadyInstalled = false;
if(file_exists('mysite/_config.php')) { if(file_exists('mysite/_config.php')) {
// Find the $database variable in the relevant config file without having to execute the config file // 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)) { if(preg_match("/\\\$database\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) {
eval($parts[0]); eval($parts[0]);
if($database) $alreadyInstalled = true; if($database) $alreadyInstalled = true;
// Assume that if $databaseConfig is defined in mysite/_config.php, then a non-environment-based installation has // Assume that if $databaseConfig is defined in mysite/_config.php, then a non-environment-based installation has
// already gone ahead // already gone ahead
} else if(preg_match("/\\\$databaseConfig\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) { } else if(preg_match("/\\\$databaseConfig\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) {
$alreadyInstalled = true; $alreadyInstalled = true;
} }
} }
if(file_exists('sapphire/silverstripe_version')) { if(file_exists('sapphire/silverstripe_version')) {
$sapphireVersionFile = file_get_contents('sapphire/silverstripe_version'); $sapphireVersionFile = file_get_contents('sapphire/silverstripe_version');
if(strstr($sapphireVersionFile, "/sapphire/trunk")) { if(strstr($sapphireVersionFile, "/sapphire/trunk")) {
$silverstripe_version = "trunk"; $silverstripe_version = "trunk";
} else { } else {
preg_match("/sapphire\/(?:(?:branches)|(?:tags))(?:\/rc)?\/([A-Za-z0-9._-]+)\/silverstripe_version/", $sapphireVersionFile, $matches); preg_match("/sapphire\/(?:(?:branches)|(?:tags))(?:\/rc)?\/([A-Za-z0-9._-]+)\/silverstripe_version/", $sapphireVersionFile, $matches);
$silverstripe_version = $matches[1]; $silverstripe_version = $matches[1];
} }
} else { } else {
$silverstripe_version = "unknown"; $silverstripe_version = "unknown";
} }
// Check requirements // Check requirements
$req = new InstallRequirements(); $req = new InstallRequirements();
$req->check(); $req->check();
if($req->hasErrors()) { if($req->hasErrors()) {
$hasErrorOtherThanDatabase = true; $hasErrorOtherThanDatabase = true;
} }
if($databaseConfig) { if($databaseConfig) {
$dbReq = new InstallRequirements(); $dbReq = new InstallRequirements();
$dbReq->checkdatabase($databaseConfig); $dbReq->checkdatabase($databaseConfig);
} }
// Actual processor // Actual processor
$installFromCli = (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == 'install'); $installFromCli = (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == 'install');
// CLI-install error message. exit(1) will halt any makefile. // CLI-install error message. exit(1) will halt any makefile.
if($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) { if($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) {
echo "Cannot install due to errors:\n"; echo "Cannot install due to errors:\n";
$req->listErrors(); $req->listErrors();
$dbReq->listErrors(); $dbReq->listErrors();
exit(1); exit(1);
} }
if((isset($_REQUEST['go']) || $installFromCli) && !$req->hasErrors() && !$dbReq->hasErrors() && $adminConfig['username'] && $adminConfig['password']) { if((isset($_REQUEST['go']) || $installFromCli) && !$req->hasErrors() && !$dbReq->hasErrors() && $adminConfig['username'] && $adminConfig['password']) {
// Confirm before reinstalling // Confirm before reinstalling
if(!isset($_REQUEST['force_reinstall']) && !$installFromCli && $alreadyInstalled) { if(!isset($_REQUEST['force_reinstall']) && !$installFromCli && $alreadyInstalled) {
include('sapphire/dev/install/config-form.html'); include('sapphire/dev/install/config-form.html');
} else { } else {
$inst = new Installer(); $inst = new Installer();
if($_REQUEST) $inst->install($_REQUEST); if($_REQUEST) $inst->install($_REQUEST);
else $inst->install(array( else $inst->install(array(
'database' => $databaseConfig['type'], 'database' => $databaseConfig['type'],
'mysql' => $databaseConfig, 'mysql' => $databaseConfig,
'admin' => $adminConfig, 'admin' => $adminConfig,
)); ));
} }
// Show the config form // Show the config form
} else { } else {
include('sapphire/dev/install/config-form.html'); include('sapphire/dev/install/config-form.html');
} }
/** /**
* This class checks requirements * This class checks requirements
* Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
* of 3 parts: * of 3 parts:
* $description[0] - The test catetgory * $description[0] - The test catetgory
* $description[1] - The test title * $description[1] - The test title
* $description[2] - The test error to show, if it goes wrong * $description[2] - The test error to show, if it goes wrong
*/ */
class InstallRequirements { class InstallRequirements {
var $errors, $warnings, $tests; var $errors, $warnings, $tests;
/** /**
* Just check that the database configuration is okay * Just check that the database configuration is okay
*/ */
function checkdatabase($databaseConfig) { function checkdatabase($databaseConfig) {
if($this->requireFunction( if($this->requireFunction(
'mysql_connect', 'mysql_connect',
array( array(
"PHP Configuration", "PHP Configuration",
"MySQL support", "MySQL support",
"MySQL support not included in PHP.") "MySQL support not included in PHP.")
) )
) { ) {
if($this->requireMySQLServer( if($this->requireMySQLServer(
$databaseConfig['server'], $databaseConfig['server'],
array( array(
"MySQL Configuration", "MySQL Configuration",
"MySQL server exists", "MySQL server exists",
"I couldn't find a MySQL server on '$databaseConfig[server]'", $databaseConfig['server'] "I couldn't find a MySQL server on '$databaseConfig[server]'", $databaseConfig['server']
) )
)) { )) {
if($this->requireMysqlConnection( if($this->requireMysqlConnection(
$databaseConfig['server'], $databaseConfig['server'],
$databaseConfig['username'], $databaseConfig['username'],
$databaseConfig['password'], $databaseConfig['password'],
array( array(
"MySQL Configuration", "MySQL Configuration",
"MySQL access credentials correct", "MySQL access credentials correct",
"That username/password doesn't work" "That username/password doesn't work"
) )
)) { )) {
@$this->requireMySQLVersion( @$this->requireMySQLVersion(
"4.1", "4.1",
array( array(
"MySQL Configuration", "MySQL Configuration",
"MySQL version at least 4.1", "MySQL version at least 4.1",
"MySQL version 4.1 is required, you only have ", "MySQL version 4.1 is required, you only have ",
"MySQL " . mysql_get_server_info() "MySQL " . mysql_get_server_info()
) )
); );
} }
$this->requireDatabaseOrCreatePermissions( $this->requireDatabaseOrCreatePermissions(
$databaseConfig['server'], $databaseConfig['server'],
$databaseConfig['username'], $databaseConfig['username'],
$databaseConfig['password'], $databaseConfig['password'],
$databaseConfig['database'], $databaseConfig['database'],
array( array(
"MySQL Configuration", "MySQL Configuration",
"Can I access/create the database", "Can I access/create the database",
"I can't create new databases and the database '$databaseConfig[database]' doesn't exist" "I can't create new databases and the database '$databaseConfig[database]' doesn't exist"
) )
); );
} }
} }
} }
/** /**
* Check everything except the database * Check everything except the database
*/ */
function check() { function check() {
$this->errors = null; $this->errors = null;
$this->requirePHPVersion('5.2.0', '5.0.4', array("PHP Configuration", "PHP5 installed", null, "PHP version " . phpversion())); $this->requirePHPVersion('5.2.0', '5.0.4', array("PHP Configuration", "PHP5 installed", null, "PHP version " . phpversion()));
// Check that we can identify the root folder successfully // Check that we can identify the root folder successfully
$this->requireFile('sapphire/dev/install/config-form.html', array("File permissions", $this->requireFile('sapphire/dev/install/config-form.html', array("File permissions",
"Does the webserver know where files are stored?", "Does the webserver know where files are stored?",
"The webserver isn't letting me identify where files are stored.", "The webserver isn't letting me identify where files are stored.",
$this->getBaseDir() $this->getBaseDir()
)); ));
$this->requireFile('mysite', array("File permissions", "mysite/ folder exists", "There's no mysite folder.")); $this->requireFile('mysite', array("File permissions", "mysite/ folder exists", "There's no mysite folder."));
$this->requireFile('sapphire', array("File permissions", "sapphire/ folder exists", "There's no sapphire folder.")); $this->requireFile('sapphire', array("File permissions", "sapphire/ folder exists", "There's no sapphire folder."));
$this->requireFile('cms', array("File permissions", "cms/ folder exists", "There's no cms folder.")); $this->requireFile('cms', array("File permissions", "cms/ folder exists", "There's no cms folder."));
$this->requireWriteable('.htaccess', array("File permissions", "Is the .htaccess file writeable?", null)); $this->requireWriteable('.htaccess', array("File permissions", "Is the .htaccess file writeable?", null));
$this->requireWriteable('mysite/_config.php', array("File permissions", "Is the mysite/_config.php file writeable?", null)); $this->requireWriteable('mysite/_config.php', array("File permissions", "Is the mysite/_config.php file writeable?", null));
$this->requireWriteable('assets', array("File permissions", "Is the assets/ folder writeable?", null)); $this->requireWriteable('assets', array("File permissions", "Is the assets/ folder writeable?", null));
$this->requireTempFolder(array('File permissions', 'Is the temporary folder writeable?', null)); $this->requireTempFolder(array('File permissions', 'Is the temporary folder writeable?', null));
// Check for web server, unless we're calling the installer from the command-line // Check for web server, unless we're calling the installer from the command-line
if(!isset($_SERVER['argv']) || !$_SERVER['argv']) { if(!isset($_SERVER['argv']) || !$_SERVER['argv']) {
$webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE'])); $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
if(!$webserver) { if(!$webserver) {
if(isset($_SERVER['SERVER_SOFTWARE'])) { if(isset($_SERVER['SERVER_SOFTWARE'])) {
if(strpos($_SERVER['SERVER_SOFTWARE'], 'IIS') !== false || if(strpos($_SERVER['SERVER_SOFTWARE'], 'IIS') !== false ||
strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) { strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
$webserver = $_SERVER['SERVER_SOFTWARE']; $webserver = $_SERVER['SERVER_SOFTWARE'];
} }
} else { } else {
$webserver = "I can't tell what webserver you are running"; $webserver = "I can't tell what webserver you are running";
} }
} }
$this->isRunningWebServer(array("Webserver Configuration", "Server software", "$webserver. Without Apache I can't tell if mod_rewrite is enabled.", $webserver)); $this->isRunningWebServer(array("Webserver Configuration", "Server software", "$webserver. Without Apache I can't tell if mod_rewrite is enabled.", $webserver));
if(function_exists('apache_get_modules')) { if(function_exists('apache_get_modules')) {
$this->requireApacheModule('mod_rewrite', array("Webserver Configuration", "mod_rewrite enabled", "You need mod_rewrite to run SilverStripe CMS, but it is not enabled.")); $this->requireApacheModule('mod_rewrite', array("Webserver Configuration", "mod_rewrite enabled", "You need mod_rewrite to run SilverStripe CMS, but it is not enabled."));
} elseif(strpos($webserver, 'IIS') !== false) { } elseif(strpos($webserver, 'IIS') !== false) {
$this->requireIISRewriteModule('IIS_UrlRewriteModule', array("Webserver Configuration", "IIS URL Rewrite Module enabled", "You need to enable the IIS URL Rewrite Module, but it is not installed or enabled. Download it for IIS 7 from http://www.iis.net/expand/URLRewrite")); $this->requireIISRewriteModule('IIS_UrlRewriteModule', array("Webserver Configuration", "IIS URL Rewrite Module enabled", "You need to enable the IIS URL Rewrite Module, but it is not installed or enabled. Download it for IIS 7 from http://www.iis.net/expand/URLRewrite"));
} else { } else {
$this->warning(array("Webserver Configuration", "URL rewrite enabled", "I can't tell whether any rewriting module is running. You may need to configure a rewriting rule yourself.")); $this->warning(array("Webserver Configuration", "URL rewrite enabled", "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.")); $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 // Check for GD support
if(!$this->requireFunction("imagecreatetruecolor", array("PHP Configuration", "GD2 support", "PHP must have GD version 2."))) { 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.")); $this->requireFunction("imagecreate", array("PHP Configuration", "GD2 support", "GD support for PHP not included."));
} }
// Check for XML support // Check for XML support
$this->requireFunction('xml_set_object', array("PHP Configuration", "XML support", "XML support not included in PHP.")); $this->requireFunction('xml_set_object', array("PHP Configuration", "XML support", "XML support not included in PHP."));
// Check for MySQL support // Check for MySQL support
$this->requireFunction('mysql_connect', array("PHP Configuration", "MySQL support", "MySQL support not included in PHP.")); $this->requireFunction('mysql_connect', array("PHP Configuration", "MySQL support", "MySQL support not included in PHP."));
// Check for token_get_all // Check for token_get_all
$this->requireFunction('token_get_all', array("PHP Configuration", "PHP Tokenizer", "PHP tokenizer support not included in PHP.")); $this->requireFunction('token_get_all', array("PHP Configuration", "PHP Tokenizer", "PHP tokenizer support not included in PHP."));
// Check memory allocation // 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"))); $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")));
// Check that troublesome classes don't exist // Check that troublesome classes don't exist
$badClasses = array('Query', 'HTTPResponse'); $badClasses = array('Query', 'HTTPResponse');
$this->requireNoClasses($badClasses, array("PHP Configuration", "Check that certain classes haven't been defined by PHP plugins", "Your version of PHP has defined some classes that conflict with SilverStripe's")); $this->requireNoClasses($badClasses, array("PHP Configuration", "Check that certain classes haven't been defined by PHP plugins", "Your version of PHP has defined some classes that conflict with SilverStripe's"));
return $this->errors; return $this->errors;
} }
function suggestPHPSetting($settingName, $settingValues, $testDetails) { function suggestPHPSetting($settingName, $settingValues, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$val = ini_get($settingName); $val = ini_get($settingName);
if(!in_array($val, $settingValues) && $val != $settingValues) { if(!in_array($val, $settingValues) && $val != $settingValues) {
$testDetails[2] = "$settingName is set to '$val' in php.ini. $testDetails[2]"; $testDetails[2] = "$settingName is set to '$val' in php.ini. $testDetails[2]";
$this->warning($testDetails); $this->warning($testDetails);
} }
} }
function requireMemory($min, $recommended, $testDetails) { function requireMemory($min, $recommended, $testDetails) {
$_SESSION['forcemem'] = false; $_SESSION['forcemem'] = false;
$mem = $this->getPHPMemory(); $mem = $this->getPHPMemory();
if($mem < (64 * 1024 * 1024)) { if($mem < (64 * 1024 * 1024)) {
ini_set('memory_limit', '64M'); ini_set('memory_limit', '64M');
$mem = $this->getPHPMemory(); $mem = $this->getPHPMemory();
$testDetails[3] = ini_get("memory_limit"); $testDetails[3] = ini_get("memory_limit");
} }
$this->testing($testDetails); $this->testing($testDetails);
if($mem < $min && $mem > 0) { if($mem < $min && $mem > 0) {
$testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated"; $testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
$this->error($testDetails); $this->error($testDetails);
} else if($mem < $recommended && $mem > 0) { } else if($mem < $recommended && $mem > 0) {
$testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated"; $testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
$this->warning($testDetails); $this->warning($testDetails);
} elseif($mem == 0) { } 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."; $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); $this->warning($testDetails);
} }
} }
function getPHPMemory() { function getPHPMemory() {
$memString = ini_get("memory_limit"); $memString = ini_get("memory_limit");
switch(strtolower(substr($memString,-1))) { switch(strtolower(substr($memString,-1))) {
case "k": case "k":
return round(substr($memString,0,-1)*1024); return round(substr($memString,0,-1)*1024);
case "m": case "m":
return round(substr($memString,0,-1)*1024*1024); return round(substr($memString,0,-1)*1024*1024);
case "g": case "g":
return round(substr($memString,0,-1)*1024*1024*1024); return round(substr($memString,0,-1)*1024*1024*1024);
default: default:
return round($memString); return round($memString);
} }
} }
function listErrors() { function listErrors() {
if($this->errors) { if($this->errors) {
echo "<p>The following problems are preventing me from installing SilverStripe CMS:</p>\n\n"; echo "<p>The following problems are preventing me from installing SilverStripe CMS:</p>\n\n";
foreach($this->errors as $error) { foreach($this->errors as $error) {
echo "<li>" . htmlentities(implode(", ", $error)) . "</li>\n"; echo "<li>" . htmlentities(implode(", ", $error)) . "</li>\n";
} }
} }
} }
function showTable($section = null) { function showTable($section = null) {
if($section) { if($section) {
$tests = $this->tests[$section]; $tests = $this->tests[$section];
echo "<table class=\"testResults\" width=\"100%\">"; echo "<table class=\"testResults\" width=\"100%\">";
foreach($tests as $test => $result) { foreach($tests as $test => $result) {
echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>"; echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
} }
echo "</table>"; echo "</table>";
} else { } else {
foreach($this->tests as $section => $tests) { foreach($this->tests as $section => $tests) {
echo "<h5>$section</h5>"; echo "<h5>$section</h5>";
echo "<table class=\"testResults\">"; echo "<table class=\"testResults\">";
foreach($tests as $test => $result) { foreach($tests as $test => $result) {
echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>"; echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
} }
echo "</table>"; echo "</table>";
} }
} }
} }
function showInstallStatus() { function showInstallStatus() {
if($this->warnings) { if($this->warnings) {
echo "I have installed SilverStripe CMS, however, you should note the following:"; echo "I have installed SilverStripe CMS, however, you should note the following:";
foreach($this->warnings as $warning) { foreach($this->warnings as $warning) {
echo "<li>" . htmlentities($warning) . "</li>"; echo "<li>" . htmlentities($warning) . "</li>";
} }
} else { } else {
if(isset($_SERVER['HTTP_HOST'])) { if(isset($_SERVER['HTTP_HOST'])) {
?> ?>
<p>I have installed SilverStripe CMS successfully!</p> <p>I have installed SilverStripe CMS successfully!</p>
<p><a href="./admin/" target="_blank">Open the CMS tool</a><br /> <p><a href="./admin/" target="_blank">Open the CMS tool</a><br />
<a href="./" target="_blank">Open the site</a></p> <a href="./" target="_blank">Open the site</a></p>
<?php <?php
} else { } else {
echo "\nSilverStripe successfully installed\n"; echo "\nSilverStripe successfully installed\n";
} }
} }
} }
function requireFunction($funcName, $testDetails) { function requireFunction($funcName, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
if(!function_exists($funcName)) $this->error($testDetails); if(!function_exists($funcName)) $this->error($testDetails);
else return true; else return true;
} }
/** /**
* Require that the given class doesn't exist * Require that the given class doesn't exist
*/ */
function requireNoClasses($classNames, $testDetails) { function requireNoClasses($classNames, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$badClasses = array(); $badClasses = array();
foreach($classNames as $className) { foreach($classNames as $className) {
if(class_exists($className)) $badClasses[] = $className; if(class_exists($className)) $badClasses[] = $className;
} }
if($badClasses) { if($badClasses) {
$testDetails[2] .= ". The following classes are at fault: " . implode(', ', $badClasses); $testDetails[2] .= ". The following classes are at fault: " . implode(', ', $badClasses);
$this->error($testDetails); $this->error($testDetails);
} }
else return true; else return true;
} }
function requirePHPVersion($recommendedVersion, $requiredVersion, $testDetails) { function requirePHPVersion($recommendedVersion, $requiredVersion, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$installedVersion = phpversion(); $installedVersion = phpversion();
if(version_compare($installedVersion, $requiredVersion, '<')) { if(version_compare($installedVersion, $requiredVersion, '<')) {
$testDetails[2] = "SilverStripe requires PHP version $requiredVersion or later.\n $testDetails[2] = "SilverStripe requires PHP version $requiredVersion or later.\n
PHP version $installedVersion is currently installed.\n PHP version $installedVersion is currently installed.\n
While SilverStripe requires at least PHP version $requiredVersion, upgrading to $recommendedVersion or later is recommended.\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."; If you are installing SilverStripe on a shared web server, please ask your web hosting provider to upgrade PHP for you.";
$this->error($testDetails); $this->error($testDetails);
return; return;
} }
if(version_compare($installedVersion, $recommendedVersion, '<')) { if(version_compare($installedVersion, $recommendedVersion, '<')) {
$testDetails[2] = "PHP version $installedVersion is currently installed.\n $testDetails[2] = "PHP version $installedVersion is currently installed.\n
Upgrading to at least PHP version $recommendedVersion is recommended.\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"; SilverStripe should run, but you may run into issues. Future releases may require a later version of PHP.\n";
$this->warning($testDetails); $this->warning($testDetails);
return; return;
} }
return true; return true;
} }
function requireFile($filename, $testDetails) { function requireFile($filename, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$filename = $this->getBaseDir() . $filename; $filename = $this->getBaseDir() . $filename;
if(!file_exists($filename)) { if(!file_exists($filename)) {
$testDetails[2] .= " (file '$filename' not found)"; $testDetails[2] .= " (file '$filename' not found)";
$this->error($testDetails); $this->error($testDetails);
} }
} }
function requireNoFile($filename, $testDetails) { function requireNoFile($filename, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$filename = $this->getBaseDir() . $filename; $filename = $this->getBaseDir() . $filename;
if(file_exists($filename)) { if(file_exists($filename)) {
$testDetails[2] .= " (file '$filename' found)"; $testDetails[2] .= " (file '$filename' found)";
$this->error($testDetails); $this->error($testDetails);
} }
} }
function moveFileOutOfTheWay($filename, $testDetails) { function moveFileOutOfTheWay($filename, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$filename = $this->getBaseDir() . $filename; $filename = $this->getBaseDir() . $filename;
if(file_exists($filename)) { if(file_exists($filename)) {
if(file_exists("$filename.bak")) rm("$filename.bak"); if(file_exists("$filename.bak")) rm("$filename.bak");
rename($filename, "$filename.bak"); rename($filename, "$filename.bak");
} }
} }
function requireWriteable($filename, $testDetails) { function requireWriteable($filename, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$filename = $this->getBaseDir() . str_replace("/", DIRECTORY_SEPARATOR,$filename); $filename = $this->getBaseDir() . str_replace("/", DIRECTORY_SEPARATOR,$filename);
if(!is_writeable($filename)) { if(!is_writeable($filename)) {
if(function_exists('posix_getgroups')) { if(function_exists('posix_getgroups')) {
$userID = posix_geteuid(); $userID = posix_geteuid();
$user = posix_getpwuid($userID); $user = posix_getpwuid($userID);
$currentOwnerID = fileowner($filename); $currentOwnerID = fileowner($filename);
$currentOwner = posix_getpwuid($currentOwnerID); $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]'. "; $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']) { if($user['name'] == $currentOwner['name']) {
$testDetails[2] .= "We recommend that you make the file writeable."; $testDetails[2] .= "We recommend that you make the file writeable.";
} else { } else {
$groups = posix_getgroups(); $groups = posix_getgroups();
foreach($groups as $group) { foreach($groups as $group) {
$groupInfo = posix_getgrgid($group); $groupInfo = posix_getgrgid($group);
if(in_array($currentOwner['name'], $groupInfo['members'])) $groupList[] = $groupInfo['name']; if(in_array($currentOwner['name'], $groupInfo['members'])) $groupList[] = $groupInfo['name'];
} }
if($groupList) { 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) $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"; . "\n\nFor example:\nchmod g+w $filename\nchgrp " . $groupList[0] . " $filename";
} else { } 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."; $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 { } else {
$testDetails[2] .= "The webserver user needs to be able to write to this file:\n$filename"; $testDetails[2] .= "The webserver user needs to be able to write to this file:\n$filename";
} }
$this->error($testDetails); $this->error($testDetails);
} }
} }
function requireTempFolder($testDetails) { function requireTempFolder($testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
if(function_exists('sys_get_temp_dir')) { if(function_exists('sys_get_temp_dir')) {
$sysTmp = sys_get_temp_dir(); $sysTmp = sys_get_temp_dir();
} elseif(isset($_ENV['TMP'])) { } elseif(isset($_ENV['TMP'])) {
$sysTmp = $_ENV['TMP']; $sysTmp = $_ENV['TMP'];
} else { } else {
@$tmpFile = tempnam('adfadsfdas',''); @$tmpFile = tempnam('adfadsfdas','');
@unlink($tmpFile); @unlink($tmpFile);
$sysTmp = dirname($tmpFile); $sysTmp = dirname($tmpFile);
} }
$worked = true; $worked = true;
$ssTmp = "$sysTmp/silverstripe-cache"; $ssTmp = "$sysTmp/silverstripe-cache";
if(!@file_exists($ssTmp)) { if(!@file_exists($ssTmp)) {
@$worked = mkdir($ssTmp); @$worked = mkdir($ssTmp);
if(!$worked) { if(!$worked) {
$ssTmp = dirname($_SERVER['SCRIPT_FILENAME']) . "/silverstripe-cache"; $ssTmp = dirname($_SERVER['SCRIPT_FILENAME']) . "/silverstripe-cache";
$worked = true; $worked = true;
if(!@file_exists($ssTmp)) { if(!@file_exists($ssTmp)) {
@$worked = mkdir($ssTmp); @$worked = mkdir($ssTmp);
} }
if(!$worked) { if(!$worked) {
$testDetails[2] = "Permission problem gaining access to a temp folder. " . $testDetails[2] = "Permission problem gaining access to a temp folder. " .
"Please create a folder named silverstripe-cache in the base folder " . "Please create a folder named silverstripe-cache in the base folder " .
"of the installation and ensure it has the adequate permissions"; "of the installation and ensure it has the adequate permissions";
$this->error($testDetails); $this->error($testDetails);
} }
} }
} }
} }
function requireApacheModule($moduleName, $testDetails) { function requireApacheModule($moduleName, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
if(!in_array($moduleName, apache_get_modules())) $this->error($testDetails); if(!in_array($moduleName, apache_get_modules())) $this->error($testDetails);
} }
function requireIISRewriteModule($moduleName, $testDetails) { function requireIISRewriteModule($moduleName, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
if(isset($_SERVER[$moduleName]) && $_SERVER[$moduleName] == 1) { if(isset($_SERVER[$moduleName]) && $_SERVER[$moduleName] == 1) {
return true; return true;
} else { } else {
$this->error($testDetails); $this->error($testDetails);
return false; return false;
} }
} }
function requireMysqlConnection($server, $username, $password, $testDetails) { function requireMysqlConnection($server, $username, $password, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$conn = @mysql_connect($server, $username, $password); $conn = @mysql_connect($server, $username, $password);
if($conn) { if($conn) {
return true; return true;
/* /*
if(mysql_query("CREATE DATABASE testing123")) { if(mysql_query("CREATE DATABASE testing123")) {
mysql_query("DROP DATABASE testing123"); mysql_query("DROP DATABASE testing123");
return true; return true;
} else { } else {
$testDetails[2] .= " (user '$username' doesn't have CREATE DATABASE permissions.)"; $testDetails[2] .= " (user '$username' doesn't have CREATE DATABASE permissions.)";
$this->error($testDetails); $this->error($testDetails);
} }
*/ */
} else { } else {
$testDetails[2] .= ": " . mysql_error(); $testDetails[2] .= ": " . mysql_error();
$this->error($testDetails); $this->error($testDetails);
} }
} }
function requireMySQLServer($server, $testDetails) { function requireMySQLServer($server, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$conn = @mysql_connect($server, null, null); $conn = @mysql_connect($server, null, null);
if($conn || mysql_errno() < 2000) { if($conn || mysql_errno() < 2000) {
return true; return true;
} else { } else {
$testDetails[2] .= ": " . mysql_error(); $testDetails[2] .= ": " . mysql_error();
$this->error($testDetails); $this->error($testDetails);
} }
} }
function requireMySQLVersion($version, $testDetails) { function requireMySQLVersion($version, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
if(!mysql_get_server_info()) { if(!mysql_get_server_info()) {
$testDetails[2] = 'Cannot determine the version of MySQL installed. Please ensure at least version 4.1 is installed.'; $testDetails[2] = 'Cannot determine the version of MySQL installed. Please ensure at least version 4.1 is installed.';
$this->warning($testDetails); $this->warning($testDetails);
} else { } else {
list($majorRequested, $minorRequested) = explode('.', $version); list($majorRequested, $minorRequested) = explode('.', $version);
$result = mysql_query('SELECT VERSION()'); $result = mysql_query('SELECT VERSION()');
$row=mysql_fetch_row($result); $row=mysql_fetch_row($result);
$version = ereg_replace("([A-Za-z-])", "", $row[0]); $version = ereg_replace("([A-Za-z-])", "", $row[0]);
list($majorHas, $minorHas) = explode('.', substr(trim($version), 0, 3)); list($majorHas, $minorHas) = explode('.', substr(trim($version), 0, 3));
if(($majorHas > $majorRequested) || ($majorHas == $majorRequested && $minorHas >= $minorRequested)) { if(($majorHas > $majorRequested) || ($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
return true; return true;
} else { } else {
$testDetails[2] .= "{$majorHas}.{$minorHas}."; $testDetails[2] .= "{$majorHas}.{$minorHas}.";
$this->error($testDetails); $this->error($testDetails);
} }
} }
} }
function requireDatabaseOrCreatePermissions($server, $username, $password, $database, $testDetails) { function requireDatabaseOrCreatePermissions($server, $username, $password, $database, $testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
$conn = @mysql_connect($server, $username, $password); $conn = @mysql_connect($server, $username, $password);
if(@mysql_select_db($database)) { if(@mysql_select_db($database)) {
$okay = "Database '$database' exists"; $okay = "Database '$database' exists";
} else { } else {
if(@mysql_query("CREATE DATABASE testing123")) { if(@mysql_query("CREATE DATABASE testing123")) {
mysql_query("DROP DATABASE testing123"); mysql_query("DROP DATABASE testing123");
$okay = "Able to create a new database"; $okay = "Able to create a new database";
} else { } else {
$testDetails[2] .= " (user '$username' doesn't have CREATE DATABASE permissions.)"; $testDetails[2] .= " (user '$username' doesn't have CREATE DATABASE permissions.)";
$this->error($testDetails); $this->error($testDetails);
return; return;
} }
} }
if($okay) { if($okay) {
$testDetails[3] = $okay; $testDetails[3] = $okay;
$this->testing($testDetails); $this->testing($testDetails);
} }
} }
function requireServerVariables($varNames, $errorMessage) { function requireServerVariables($varNames, $errorMessage) {
//$this->testing($testDetails); //$this->testing($testDetails);
foreach($varNames as $varName) { foreach($varNames as $varName) {
if(!$_SERVER[$varName]) $missing[] = '$_SERVER[' . $varName . ']'; if(!$_SERVER[$varName]) $missing[] = '$_SERVER[' . $varName . ']';
} }
if(!isset($missing)) { if(!isset($missing)) {
return true; return true;
} else { } else {
$testDetails[2] .= " (the following PHP variables are missing: " . implode(", ", $missing) . ")"; $testDetails[2] .= " (the following PHP variables are missing: " . implode(", ", $missing) . ")";
$this->error($testDetails); $this->error($testDetails);
} }
} }
function isRunningWebServer($testDetails) { function isRunningWebServer($testDetails) {
$this->testing($testDetails); $this->testing($testDetails);
if(function_exists('apache_get_modules') || stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) { if(function_exists('apache_get_modules') || stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
return true; return true;
} elseif(strpos($_SERVER['SERVER_SOFTWARE'], 'IIS') !== false) { } elseif(strpos($_SERVER['SERVER_SOFTWARE'], 'IIS') !== false) {
return true; return true;
} else { } else {
$this->warning($testDetails); $this->warning($testDetails);
return false; return false;
} }
} }
// Must be PHP4 compatible // Must be PHP4 compatible
var $baseDir; var $baseDir;
function getBaseDir() { function getBaseDir() {
// Cache the value so that when the installer mucks with SCRIPT_FILENAME half way through, this method // Cache the value so that when the installer mucks with SCRIPT_FILENAME half way through, this method
// still returns the correct value. // still returns the correct value.
if(!$this->baseDir) $this->baseDir = realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . DIRECTORY_SEPARATOR; if(!$this->baseDir) $this->baseDir = realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . DIRECTORY_SEPARATOR;
return $this->baseDir; return $this->baseDir;
} }
function testing($testDetails) { function testing($testDetails) {
if(!$testDetails) return; if(!$testDetails) return;
$section = $testDetails[0]; $section = $testDetails[0];
$test = $testDetails[1]; $test = $testDetails[1];
$message = "OK"; $message = "OK";
if(isset($testDetails[3])) $message .= " ($testDetails[3])"; if(isset($testDetails[3])) $message .= " ($testDetails[3])";
$this->tests[$section][$test] = array("good", $message); $this->tests[$section][$test] = array("good", $message);
} }
function error($testDetails) { function error($testDetails) {
$section = $testDetails[0]; $section = $testDetails[0];
$test = $testDetails[1]; $test = $testDetails[1];
$this->tests[$section][$test] = array("error", $testDetails[2]); $this->tests[$section][$test] = array("error", $testDetails[2]);
$this->errors[] = $testDetails; $this->errors[] = $testDetails;
} }
function warning($testDetails) { function warning($testDetails) {
$section = $testDetails[0]; $section = $testDetails[0];
$test = $testDetails[1]; $test = $testDetails[1];
$this->tests[$section][$test] = array("warning", $testDetails[2]); $this->tests[$section][$test] = array("warning", $testDetails[2]);
$this->warnings[] = $testDetails; $this->warnings[] = $testDetails;
} }
function hasErrors() { function hasErrors() {
return sizeof($this->errors); return sizeof($this->errors);
} }
function hasWarnings() { function hasWarnings() {
return sizeof($this->warnings); return sizeof($this->warnings);
} }
} }
class Installer extends InstallRequirements { class Installer extends InstallRequirements {
function __construct() { function __construct() {
// Cache the baseDir value // Cache the baseDir value
$this->getBaseDir(); $this->getBaseDir();
} }
function install($config) { function install($config) {
if(isset($_SERVER['HTTP_HOST'])) { if(isset($_SERVER['HTTP_HOST'])) {
?> ?>
<html> <html>
<head> <head>
<title>PHP 5 is required</title> <title>PHP 5 is required</title>
<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/layout.css" /> <link rel="stylesheet" type="text/css" href="themes/blackcandy/css/layout.css" />
<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/typography.css" /> <link rel="stylesheet" type="text/css" href="themes/blackcandy/css/typography.css" />
<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/form.css" /> <link rel="stylesheet" type="text/css" href="themes/blackcandy/css/form.css" />
<link rel="stylesheet" type="text/css" href="sapphire/dev/install/install.css" /> <link rel="stylesheet" type="text/css" href="sapphire/dev/install/install.css" />
<script src="sapphire/thirdparty/jquery/jquery.js"></script> <script src="sapphire/thirdparty/jquery/jquery.js"></script>
</head> </head>
<body> <body>
<div id="BgContainer"> <div id="BgContainer">
<div id="Container"> <div id="Container">
<div id="Header"> <div id="Header">
<h1>SilverStripe CMS Installation</h1> <h1>SilverStripe CMS Installation</h1>
</div> </div>
<div id="Navigation">&nbsp;</div> <div id="Navigation">&nbsp;</div>
<div class="clear"><!-- --></div> <div class="clear"><!-- --></div>
<div id="Layout"> <div id="Layout">
<div class="typography"> <div class="typography">
<h1>Installing SilverStripe...</h1> <h1>Installing SilverStripe...</h1>
<p>I am now running through the installation steps (this should take about 30 seconds)</p> <p>I am now running through the installation steps (this should take about 30 seconds)</p>
<p>If you receive a fatal error, refresh this page to continue the installation</p> <p>If you receive a fatal error, refresh this page to continue the installation</p>
<ul> <ul>
<?php <?php
} else { } else {
echo "SILVERSTRIPE COMMAND-LINE INSTALLATION\n\n"; echo "SILVERSTRIPE COMMAND-LINE INSTALLATION\n\n";
} }
flush(); flush();
if(isset($_POST['stats'])) { if(isset($_POST['stats'])) {
if(file_exists('sapphire/silverstripe_version')) { if(file_exists('sapphire/silverstripe_version')) {
$sapphireVersionFile = file_get_contents('sapphire/silverstripe_version'); $sapphireVersionFile = file_get_contents('sapphire/silverstripe_version');
if(strstr($sapphireVersionFile, "/sapphire/trunk")) { if(strstr($sapphireVersionFile, "/sapphire/trunk")) {
$silverstripe_version = "trunk"; $silverstripe_version = "trunk";
} else { } else {
preg_match("/sapphire\/(?:(?:branches)|(?:tags))(?:\/rc)?\/([A-Za-z0-9._-]+)\/silverstripe_version/", $sapphireVersionFile, $matches); preg_match("/sapphire\/(?:(?:branches)|(?:tags))(?:\/rc)?\/([A-Za-z0-9._-]+)\/silverstripe_version/", $sapphireVersionFile, $matches);
$silverstripe_version = $matches[1]; $silverstripe_version = $matches[1];
} }
} else { } else {
$silverstripe_version = "unknown"; $silverstripe_version = "unknown";
} }
$phpVersion = urlencode(phpversion()); $phpVersion = urlencode(phpversion());
$conn = @mysql_connect($config['mysql']['server'], null, null); $conn = @mysql_connect($config['mysql']['server'], null, null);
$databaseVersion = urlencode('MySQL ' . mysql_get_server_info()); $databaseVersion = urlencode('MySQL ' . mysql_get_server_info());
$webserver = urlencode($_SERVER['SERVER_SOFTWARE']); $webserver = urlencode($_SERVER['SERVER_SOFTWARE']);
$url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$webserver"; $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$webserver";
if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) { if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
$url .= '&ID=' . $_SESSION['StatsID']; $url .= '&ID=' . $_SESSION['StatsID'];
} }
@$_SESSION['StatsID'] = file_get_contents($url); @$_SESSION['StatsID'] = file_get_contents($url);
} }
if(file_exists('mysite/_config.php')) { if(file_exists('mysite/_config.php')) {
unlink('mysite/_config.php'); unlink('mysite/_config.php');
} }
$theme = isset($_POST['template']) ? $_POST['template'] : 'blackcandy'; $theme = isset($_POST['template']) ? $_POST['template'] : 'blackcandy';
// Write the config file // Write the config file
global $usingEnv; global $usingEnv;
if($usingEnv) { if($usingEnv) {
$this->statusMessage("Creating 'mysite/_config.php' for use with _ss_environment.php..."); $this->statusMessage("Creating 'mysite/_config.php' for use with _ss_environment.php...");
$this->createFile("mysite/_config.php", <<<PHP $this->createFile("mysite/_config.php", <<<PHP
<?php <?php
global \$project; global \$project;
\$project = 'mysite'; \$project = 'mysite';
global \$database; global \$database;
\$database = "{$config['mysql']['database']}"; \$database = "{$config['mysql']['database']}";
require_once("conf/ConfigureFromEnv.php"); require_once("conf/ConfigureFromEnv.php");
MySQLDatabase::set_connection_charset('utf8'); MySQLDatabase::set_connection_charset('utf8');
// This line set's the current theme. More themes can be // This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/ // downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme'); SSViewer::set_theme('$theme');
// enable nested URLs for this site (e.g. page/sub-page/) // enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls(); SiteTree::enable_nested_urls();
?> ?>
PHP PHP
); );
} else { } else {
$this->statusMessage("Creating 'mysite/_config.php'..."); $this->statusMessage("Creating 'mysite/_config.php'...");
$devServers = $this->var_export_array_nokeys(explode("\n", $_POST['devsites'])); $devServers = $this->var_export_array_nokeys(explode("\n", $_POST['devsites']));
$escapedPassword = addslashes($config['mysql']['password']); $escapedPassword = addslashes($config['mysql']['password']);
$this->createFile("mysite/_config.php", <<<PHP $this->createFile("mysite/_config.php", <<<PHP
<?php <?php
global \$project; global \$project;
\$project = 'mysite'; \$project = 'mysite';
global \$databaseConfig; global \$databaseConfig;
\$databaseConfig = array( \$databaseConfig = array(
"type" => "$config[database]", "type" => "$config[database]",
"server" => "{$config['mysql']['server']}", "server" => "{$config['mysql']['server']}",
"username" => "{$config['mysql']['username']}", "username" => "{$config['mysql']['username']}",
"password" => '{$escapedPassword}', "password" => '{$escapedPassword}',
"database" => "{$config['mysql']['database']}", "database" => "{$config['mysql']['database']}",
); );
// Sites running on the following servers will be // Sites running on the following servers will be
// run in development mode. See // run in development mode. See
// http://doc.silverstripe.org/doku.php?id=configuration // http://doc.silverstripe.org/doku.php?id=configuration
// for a description of what dev mode does. // for a description of what dev mode does.
Director::set_dev_servers($devServers); Director::set_dev_servers($devServers);
// This line set's the current theme. More themes can be // This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/ // downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme'); SSViewer::set_theme('$theme');
// enable nested URLs for this site (e.g. page/sub-page/) // enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls(); SiteTree::enable_nested_urls();
?> ?>
PHP PHP
); );
} }
$this->statusMessage("Creating '.htaccess' file..."); $this->statusMessage("Creating '.htaccess' file...");
$this->createHtaccess(); $this->createHtaccess();
// Load the sapphire runtime // Load the sapphire runtime
$_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/sapphire/main.php'; $_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/sapphire/main.php';
chdir('sapphire'); chdir('sapphire');
// Rebuild the manifest // Rebuild the manifest
$_GET['flush'] = true; $_GET['flush'] = true;
// Show errors as if you're in development mode // Show errors as if you're in development mode
$_SESSION['isDev'] = 1; $_SESSION['isDev'] = 1;
require_once('core/Core.php'); require_once('core/Core.php');
$this->statusMessage("Building database schema..."); $this->statusMessage("Building database schema...");
// Build database // Build database
$con = new Controller(); $con = new Controller();
$con->pushCurrent(); $con->pushCurrent();
global $databaseConfig; global $databaseConfig;
DB::connect($databaseConfig); DB::connect($databaseConfig);
$dbAdmin = new DatabaseAdmin(); $dbAdmin = new DatabaseAdmin();
$dbAdmin->init(); $dbAdmin->init();
$_REQUEST['username'] = $config['admin']['username']; $_REQUEST['username'] = $config['admin']['username'];
$_REQUEST['password'] = $config['admin']['password']; $_REQUEST['password'] = $config['admin']['password'];
$dbAdmin->doBuild(true); $dbAdmin->doBuild(true);
$adminmember = DataObject::get_one('Member',"\"Email\"= '".$_REQUEST['admin']['username']."'"); $adminmember = DataObject::get_one('Member',"\"Email\"= '".$_REQUEST['admin']['username']."'");
if($adminmember) { if($adminmember) {
$adminmember->FirstName = $_REQUEST['admin']['firstname']; $adminmember->FirstName = $_REQUEST['admin']['firstname'];
$adminmember->Surname = $_REQUEST['admin']['surname']; $adminmember->Surname = $_REQUEST['admin']['surname'];
$adminmember->write(); $adminmember->write();
} }
// Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266) // Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266)
FileSystem::sync(); FileSystem::sync();
$_SESSION['username'] = $config['admin']['username']; $_SESSION['username'] = $config['admin']['username'];
$_SESSION['password'] = $config['admin']['password']; $_SESSION['password'] = $config['admin']['password'];
if(!$this->errors) { if(!$this->errors) {
if(isset($_SERVER['HTTP_HOST'])) { if(isset($_SERVER['HTTP_HOST'])) {
$this->statusMessage("Checking that friendly URLs work..."); $this->statusMessage("Checking that friendly URLs work...");
$this->checkModRewrite(); $this->checkModRewrite();
} else { } else {
echo "\n\nSilverStripe successfully installed\n"; echo "\n\nSilverStripe successfully installed\n";
} }
} }
return $this->errors; return $this->errors;
} }
function makeFolder($folder) { function makeFolder($folder) {
$base = $this->getBaseDir(); $base = $this->getBaseDir();
if(!file_exists($base . $folder)) { if(!file_exists($base . $folder)) {
if(!mkdir($base . $folder, 02775)) { if(!mkdir($base . $folder, 02775)) {
$this->error("Couldn't create a folder called $base$folder"); $this->error("Couldn't create a folder called $base$folder");
} else { } else {
chmod($base . $folder, 02775); chmod($base . $folder, 02775);
} }
} }
} }
function renameFolder($oldName, $newName) { function renameFolder($oldName, $newName) {
if($oldName == $newName) return true; if($oldName == $newName) return true;
$base = $this->getBaseDir(); $base = $this->getBaseDir();
if(!rename($base . $oldName, $base . $newName)) { if(!rename($base . $oldName, $base . $newName)) {
$this->error("Couldn't rename $base$oldName to $base$newName"); $this->error("Couldn't rename $base$oldName to $base$newName");
return false; return false;
} else { } else {
return true; return true;
} }
} }
function copyFolder($oldName, $newName) { function copyFolder($oldName, $newName) {
if($oldName == $newName) return true; if($oldName == $newName) return true;
$base = $this->getBaseDir(); $base = $this->getBaseDir();
if(!copyr($base . $oldName, $base . $newName)) { if(!copyr($base . $oldName, $base . $newName)) {
$this->error("Couldn't rename $base$oldName to $base$newName"); $this->error("Couldn't rename $base$oldName to $base$newName");
return false; return false;
} else { } else {
return true; return true;
} }
} }
function createFile($filename, $content) { function createFile($filename, $content) {
$base = $this->getBaseDir(); $base = $this->getBaseDir();
$this->statusMessage("Creating $base$filename"); $this->statusMessage("Creating $base$filename");
if((@$fh = fopen($base . $filename, 'w')) && fwrite($fh, $content) && fclose($fh)) { if((@$fh = fopen($base . $filename, 'w')) && fwrite($fh, $content) && fclose($fh)) {
return true; return true;
} else { } else {
$this->error("Couldn't write to file $base$filename"); $this->error("Couldn't write to file $base$filename");
} }
} }
function createHtaccess() { function createHtaccess() {
$start = "### SILVERSTRIPE START ###\n"; $start = "### SILVERSTRIPE START ###\n";
$end = "\n### SILVERSTRIPE END ###"; $end = "\n### SILVERSTRIPE END ###";
$base = dirname($_SERVER['SCRIPT_NAME']); $base = dirname($_SERVER['SCRIPT_NAME']);
if(defined('DIRECTORY_SEPARATOR')) $base = str_replace(DIRECTORY_SEPARATOR, '/', $base); if(defined('DIRECTORY_SEPARATOR')) $base = str_replace(DIRECTORY_SEPARATOR, '/', $base);
else $base = str_replace("\\", '/', $base); else $base = str_replace("\\", '/', $base);
if($base != '.') $baseClause = "RewriteBase $base\n"; if($base != '.') $baseClause = "RewriteBase $base\n";
else $baseClause = ""; else $baseClause = "";
$rewrite = <<<TEXT $rewrite = <<<TEXT
<Files *.ss> <Files *.ss>
Order deny,allow Order deny,allow
Deny from all Deny from all
Allow from 127.0.0.1 Allow from 127.0.0.1
</Files> </Files>
RewriteEngine On RewriteEngine On
$baseClause $baseClause
RewriteCond %{REQUEST_URI} !(\.gif$)|(\.jpg$)|(\.png$)|(\.css$)|(\.js$) RewriteCond %{REQUEST_URI} !(\.gif$)|(\.jpg$)|(\.png$)|(\.css$)|(\.js$)
RewriteCond %{REQUEST_URI} ^(.*)$ RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* sapphire/main.php?url=%1&%{QUERY_STRING} [L] RewriteRule .* sapphire/main.php?url=%1&%{QUERY_STRING} [L]
TEXT TEXT
; ;
if(file_exists('.htaccess')) { if(file_exists('.htaccess')) {
$htaccess = file_get_contents('.htaccess'); $htaccess = file_get_contents('.htaccess');
if(strpos($htaccess, '### SILVERSTRIPE START ###') === false && strpos($htaccess, '### SILVERSTRIPE END ###') === false) { if(strpos($htaccess, '### SILVERSTRIPE START ###') === false && strpos($htaccess, '### SILVERSTRIPE END ###') === false) {
$htaccess .= "\n### SILVERSTRIPE START ###\n### SILVERSTRIPE END ###\n"; $htaccess .= "\n### SILVERSTRIPE START ###\n### SILVERSTRIPE END ###\n";
} }
if(strpos($htaccess, '### SILVERSTRIPE START ###') !== false && strpos($htaccess, '### SILVERSTRIPE END ###') !== false) { if(strpos($htaccess, '### SILVERSTRIPE START ###') !== false && strpos($htaccess, '### SILVERSTRIPE END ###') !== false) {
$start = substr($htaccess, 0, strpos($htaccess, '### SILVERSTRIPE START ###')) . "### SILVERSTRIPE START ###\n"; $start = substr($htaccess, 0, strpos($htaccess, '### SILVERSTRIPE START ###')) . "### SILVERSTRIPE START ###\n";
$end = "\n" . substr($htaccess, strpos($htaccess, '### SILVERSTRIPE END ###')); $end = "\n" . substr($htaccess, strpos($htaccess, '### SILVERSTRIPE END ###'));
} }
} }
$this->createFile('.htaccess', $start . $rewrite . $end); $this->createFile('.htaccess', $start . $rewrite . $end);
} }
function restoreHtaccess() { function restoreHtaccess() {
$start = "### SILVERSTRIPE START ###\n"; $start = "### SILVERSTRIPE START ###\n";
$end= "\n### SILVERSTRIPE END ###"; $end= "\n### SILVERSTRIPE END ###";
if(file_exists('.htaccess')) { if(file_exists('.htaccess')) {
$htaccess = file_get_contents('.htaccess'); $htaccess = file_get_contents('.htaccess');
if(strpos($htaccess, '### SILVERSTRIPE START ###') === false && strpos($htaccess, '### SILVERSTRIPE END ###') === false) { if(strpos($htaccess, '### SILVERSTRIPE START ###') === false && strpos($htaccess, '### SILVERSTRIPE END ###') === false) {
$htaccess .= "\n### SILVERSTRIPE START ###\n### SILVERSTRIPE END ###\n"; $htaccess .= "\n### SILVERSTRIPE START ###\n### SILVERSTRIPE END ###\n";
} }
if(strpos($htaccess, '### SILVERSTRIPE START ###') !== false && strpos($htaccess, '### SILVERSTRIPE END ###') !== false) { if(strpos($htaccess, '### SILVERSTRIPE START ###') !== false && strpos($htaccess, '### SILVERSTRIPE END ###') !== false) {
$start = substr($htaccess, 0, strpos($htaccess, '### SILVERSTRIPE START ###')) . "### SILVERSTRIPE START ###\n"; $start = substr($htaccess, 0, strpos($htaccess, '### SILVERSTRIPE START ###')) . "### SILVERSTRIPE START ###\n";
$end = "\n" . substr($htaccess, strpos($htaccess, '### SILVERSTRIPE END ###')); $end = "\n" . substr($htaccess, strpos($htaccess, '### SILVERSTRIPE END ###'));
} }
} }
$this->createFile('.htaccess', $start . $end); $this->createFile('.htaccess', $start . $end);
} }
function checkModRewrite() { function checkModRewrite() {
if(!isset($_SERVER['HTTP_HOST']) || !$_SERVER['HTTP_HOST']) { if(!isset($_SERVER['HTTP_HOST']) || !$_SERVER['HTTP_HOST']) {
$this->statusMessage("Installer seems to be called from command-line, we're going to assume that rewriting is working."); $this->statusMessage("Installer seems to be called from command-line, we're going to assume that rewriting is working.");
return true; return true;
} }
echo <<<HTML echo <<<HTML
<li id="ModRewriteResult">Testing...</li> <li id="ModRewriteResult">Testing...</li>
<script> <script>
if(typeof $ == 'undefined') { if(typeof $ == 'undefined') {
document.getElemenyById('ModeRewriteResult').innerHTML = "I can't run jQuery ajax to set rewriting; I will redirect you to the homepage to see if everything is working."; document.getElemenyById('ModeRewriteResult').innerHTML = "I can't run jQuery ajax to set rewriting; I will redirect you to the homepage to see if everything is working.";
setTimeout(function() { setTimeout(function() {
window.location = "home/successfullyinstalled?flush=1"; window.location = "home/successfullyinstalled?flush=1";
}, 10000); }, 10000);
} else { } else {
$.ajax({ $.ajax({
method: 'get', method: 'get',
url: 'InstallerTest/testrewrite', url: 'InstallerTest/testrewrite',
complete: function(response) { complete: function(response) {
if(response.responseText == 'OK') { if(response.responseText == 'OK') {
$('#ModRewriteResult').html("Friendly URLs set up successfully; I am now redirecting you to your SilverStripe site...") $('#ModRewriteResult').html("Friendly URLs set up successfully; I am now redirecting you to your SilverStripe site...")
setTimeout(function() { setTimeout(function() {
window.location = "home/successfullyinstalled?flush=1"; window.location = "home/successfullyinstalled?flush=1";
}, 2000); }, 2000);
} else { } else {
$('#ModRewriteResult').html("Friendly URLs are not working. This is most likely because mod_rewrite isn't configured" $('#ModRewriteResult').html("Friendly URLs are not working. This is most likely because mod_rewrite isn't configured"
+ "correctly on your site. Please check the following things in your Apache configuration; " + "correctly on your site. Please check the following things in your Apache configuration; "
+ " you may need to get your web host or server administrator to do this for you:" + " you may need to get your web host or server administrator to do this for you:"
+ "<ul><li>mod_rewrite is enabled</li><li>AllowOverride All is set for your directory</li></ul>"); + "<ul><li>mod_rewrite is enabled</li><li>AllowOverride All is set for your directory</li></ul>");
} }
} }
}); });
} }
</script> </script>
<noscript> <noscript>
<li><a href="home/successfullyinstalled?flush=1">Click here to check friendly URLs are working. If you get a 404 then something is wrong.</li> <li><a href="home/successfullyinstalled?flush=1">Click here to check friendly URLs are working. If you get a 404 then something is wrong.</li>
</noscript> </noscript>
HTML; HTML;
} }
function var_export_array_nokeys($array) { function var_export_array_nokeys($array) {
$retval = "array(\n"; $retval = "array(\n";
foreach($array as $item) { foreach($array as $item) {
$retval .= "\t'"; $retval .= "\t'";
$retval .= trim($item); $retval .= trim($item);
$retval .= "',\n"; $retval .= "',\n";
} }
$retval .= ")"; $retval .= ")";
return $retval; return $retval;
} }
/** /**
* Show an installation status message. * Show an installation status message.
* The output differs depending on whether this is CLI or web based * The output differs depending on whether this is CLI or web based
*/ */
function statusMessage($msg) { function statusMessage($msg) {
if(isset($_SERVER['HTTP_HOST'])) echo "<li>$msg</li>\n"; if(isset($_SERVER['HTTP_HOST'])) echo "<li>$msg</li>\n";
else echo "$msg\n"; else echo "$msg\n";
flush(); flush();
} }
} }
/** /**
* Copy a file, or recursively copy a folder and its contents * Copy a file, or recursively copy a folder and its contents
* *
* @author Aidan Lister <aidan@php.net> * @author Aidan Lister <aidan@php.net>
* @version 1.0.1 * @version 1.0.1
* @link http://aidanlister.com/repos/v/function.copyr.php * @link http://aidanlister.com/repos/v/function.copyr.php
* @param string $source Source path * @param string $source Source path
* @param string $dest Destination path * @param string $dest Destination path
* @return bool Returns TRUE on success, FALSE on failure * @return bool Returns TRUE on success, FALSE on failure
*/ */
function copyr($source, $dest) function copyr($source, $dest)
{ {
// Simple copy for a file // Simple copy for a file
if (is_file($source)) { if (is_file($source)) {
return copy($source, $dest); return copy($source, $dest);
} }
// Make destination directory // Make destination directory
if (!is_dir($dest)) { if (!is_dir($dest)) {
mkdir($dest); mkdir($dest);
} }
// Loop through the folder // Loop through the folder
$dir = dir($source); $dir = dir($source);
while (false !== $entry = $dir->read()) { while (false !== $entry = $dir->read()) {
// Skip pointers // Skip pointers
if ($entry == '.' || $entry == '..') { if ($entry == '.' || $entry == '..') {
continue; continue;
} }
// Deep copy directories // Deep copy directories
if ($dest !== "$source/$entry") { if ($dest !== "$source/$entry") {
copyr("$source/$entry", "$dest/$entry"); copyr("$source/$entry", "$dest/$entry");
} }
} }
// Clean up // Clean up
$dir->close(); $dir->close();
return true; return true;
} }
function rm($fileglob) function rm($fileglob)
{ {
if (is_string($fileglob)) { if (is_string($fileglob)) {
if (is_file($fileglob)) { if (is_file($fileglob)) {
return unlink($fileglob); return unlink($fileglob);
} else if (is_dir($fileglob)) { } else if (is_dir($fileglob)) {
$ok = rm("$fileglob/*"); $ok = rm("$fileglob/*");
if (! $ok) { if (! $ok) {
return false; return false;
} }
return rmdir($fileglob); return rmdir($fileglob);
} else { } else {
$matching = glob($fileglob); $matching = glob($fileglob);
if ($matching === false) { if ($matching === false) {
trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING); trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING);
return false; return false;
} }
$rcs = array_map('rm', $matching); $rcs = array_map('rm', $matching);
if (in_array(false, $rcs)) { if (in_array(false, $rcs)) {
return false; return false;
} }
} }
} else if (is_array($fileglob)) { } else if (is_array($fileglob)) {
$rcs = array_map('rm', $fileglob); $rcs = array_map('rm', $fileglob);
if (in_array(false, $rcs)) { if (in_array(false, $rcs)) {
return false; return false;
} }
} else { } else {
trigger_error('Param #1 must be filename or glob pattern, or array of filenames or glob patterns', E_USER_ERROR); trigger_error('Param #1 must be filename or glob pattern, or array of filenames or glob patterns', E_USER_ERROR);
return false; return false;
} }
return true; return true;
} }
?> ?>