2008-11-22 04:36:31 +01:00
< ? php
/**
* SilverStripe CMS Installer
* This installer doesn 't use any of the fancy Sapphire stuff in case it' s unsupported .
*/
ini_set ( 'max_execution_time' , 0 );
error_reporting ( E_ALL ^ E_NOTICE );
session_start ();
// Include environment files
$usingEnv = false ;
$envFiles = array ( '_ss_environment.php' , '../_ss_environment.php' , '../../_ss_environment.php' );
foreach ( $envFiles as $envFile ) {
if ( @ file_exists ( $envFile )) {
include_once ( $envFile );
$usingEnv = true ;
break ;
}
}
// Load database config
if ( isset ( $_REQUEST [ 'mysql' ])) {
$databaseConfig = $_REQUEST [ 'mysql' ];
} else {
$_REQUEST [ 'mysql' ] = $databaseConfig = array (
" type " => " MySQLDatabase " ,
" 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' ])) {
$adminConfig = $_REQUEST [ 'admin' ];
} else {
$_REQUEST [ 'admin' ] = $adminConfig = array (
'username' => 'admin' ,
'password' => 'password' ,
'firstname' => '' ,
'surname' => ''
);
}
$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 ( 'sapphire/silverstripe_version' )) {
$sapphireVersionFile = file_get_contents ( 'sapphire/silverstripe_version' );
if ( strstr ( $sapphireVersionFile , " /sapphire/trunk " )) {
$silverstripe_version = " trunk " ;
} else {
preg_match ( " /sapphire \ /(?:(?:branches)|(?:tags))(?: \ /rc)? \ /([A-Za-z0-9._-]+) \ /silverstripe_version/ " , $sapphireVersionFile , $matches );
$silverstripe_version = $matches [ 1 ];
}
} else {
$silverstripe_version = " unknown " ;
}
// Check requirements
$req = new InstallRequirements ();
$req -> check ();
if ( $req -> hasErrors ()) {
$hasErrorOtherThanDatabase = true ;
}
if ( $databaseConfig ) {
$dbReq = new InstallRequirements ();
$dbReq -> checkdatabase ( $databaseConfig );
}
// 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 ()) {
// Confirm before reinstalling
if ( ! isset ( $_REQUEST [ 'force_reinstall' ]) && ! $installFromCli && $alreadyInstalled ) {
include ( 'config-form.html' );
} else {
$inst = new Installer ();
if ( $_REQUEST ) $inst -> install ( $_REQUEST );
else $inst -> install ( array (
'database' => $databaseConfig [ 'type' ],
'mysql' => $databaseConfig ,
'admin' => $adminConfig ,
));
}
// Show the config form
} else {
include ( '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 ;
/**
* Just check that the database configuration is okay
*/
function checkdatabase ( $databaseConfig ) {
if ( $this -> requireFunction ( 'mysql_connect' , array ( " PHP Configuration " , " MySQL support " , " MySQL support not included in PHP. " ))) {
if ( $this -> requireMysqlConnection ( $databaseConfig [ 'server' ], $databaseConfig [ 'username' ], $databaseConfig [ 'password' ],
2009-06-28 03:38:19 +02:00
array ( " MySQL Configuration " , " Can I access the server with the given credentials? " , " That username/password doesn't work " ))) {
2008-11-22 04:36:31 +01:00
@ $this -> requireMySQLVersion ( " 4.1 " , array ( " MySQL Configuration " , " MySQL version at least 4.1 " , " MySQL version 4.1 is required, you only have " , " MySQL " . mysql_get_server_info ()));
}
$this -> requireDatabaseOrCreatePermissions ( $databaseConfig [ 'server' ], $databaseConfig [ 'username' ], $databaseConfig [ 'password' ], $databaseConfig [ 'database' ],
array ( " MySQL Configuration " , " Can I access/create the database " , " I can't create new databases and the database ' $databaseConfig[database] ' doesn't exist " ));
}
}
/**
* Check everything except the database
*/
function check () {
$this -> errors = null ;
$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
$this -> requireFile ( '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 -> 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 ( 'cms' , array ( " File permissions " , " cms/ folder exists " , " There's no cms folder. " ));
$this -> requireFile ( 'jsparty' , array ( " File permissions " , " jsparty/ folder exists " , " There's no jsparty folder. " ));
$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 ( 'assets' , array ( " File permissions " , " Is the assets/ 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
if ( ! isset ( $_SERVER [ 'argv' ]) || ! $_SERVER [ 'argv' ]) {
$webserver = strip_tags ( trim ( $_SERVER [ 'SERVER_SIGNATURE' ]));
if ( $webserver == '' ) {
$webserver = " I can't tell what webserver you are running " ;
}
$this -> isRunningApache ( array ( " Webserver Configuration " , " Server software " , " $webserver . Without Apache I can't tell if mod_rewrite is enabled. " , $webserver ));
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. " ));
} else {
$this -> warning ( array ( " Webserver Configuration " , " mod_rewrite enabled " , " I can't tell whether mod_rewrite 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. " ));
// Check for MySQL support
$this -> requireFunction ( 'mysql_connect' , array ( " PHP Configuration " , " MySQL support " , " MySQL support not included in PHP. " ));
2009-10-31 01:57:27 +01:00
// Check for token_get_all
$this -> requireFunction ( 'token_get_all' , array ( " PHP Configuration " , " PHP Tokenizer " , " PHP tokenizer support not included in PHP. " ));
2008-11-22 04:36:31 +01:00
// 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 " )));
2009-11-19 21:29:20 +01:00
// Check that troublesome classes don't exist
$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 " ));
2008-11-22 04:36:31 +01:00
// Check allow_call_time_pass_reference
$this -> suggestPHPSetting ( 'allow_call_time_pass_reference' , array ( 1 , '1' , 'on' , 'On' ), array ( " PHP Configuration " , " Check that the php.ini setting allow_call_time_pass_reference is on " ,
" You can install with allow_call_time_pass_reference not set, but some warnings may get displayed. For best results, turn it on. " ));
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 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 " <p>The following problems are preventing me from installing SilverStripe CMS:</p> \n \n " ;
foreach ( $this -> errors as $error ) {
echo " <li> " . htmlentities ( implode ( " , " , $error )) . " </li> \n " ;
}
}
}
function showTable ( $section = null ) {
if ( $section ) {
$tests = $this -> tests [ $section ];
echo " <table class= \" testResults \" width= \" 100% \" > " ;
foreach ( $tests as $test => $result ) {
echo " <tr class= \" $result[0] \" ><td> $test </td><td> " . nl2br ( htmlentities ( $result [ 1 ])) . " </td></tr> " ;
}
echo " </table> " ;
} else {
foreach ( $this -> tests as $section => $tests ) {
echo " <h5> $section </h5> " ;
echo " <table class= \" testResults \" > " ;
foreach ( $tests as $test => $result ) {
echo " <tr class= \" $result[0] \" ><td> $test </td><td> " . nl2br ( htmlentities ( $result [ 1 ])) . " </td></tr> " ;
}
echo " </table> " ;
}
}
}
function showInstallStatus () {
if ( $this -> warnings ) {
echo " I have installed SilverStripe CMS, however, you should note the following: " ;
foreach ( $this -> warnings as $warning ) {
echo " <li> " . htmlentities ( $warning ) . " </li> " ;
}
} else {
if ( isset ( $_SERVER [ 'HTTP_HOST' ])) {
?>
< p > I have installed SilverStripe CMS successfully !</ p >
< p >< a href = " ./admin/ " target = " _blank " > Open the CMS tool </ a >< br />
< a href = " ./ " target = " _blank " > Open the site </ a ></ p >
< ? php
} else {
echo " \n SilverStripe successfully installed \n " ;
}
}
}
function requireFunction ( $funcName , $testDetails ) {
$this -> testing ( $testDetails );
if ( ! function_exists ( $funcName )) $this -> error ( $testDetails );
else return true ;
}
2009-11-19 21:29:20 +01:00
/**
* Require that the given class doesn ' t exist
*/
function requireNoClasses ( $classNames , $testDetails ) {
$this -> testing ( $testDetails );
$badClasses = array ();
foreach ( $classNames as $className ) {
if ( class_exists ( $className )) $badClasses [] = $className ;
}
if ( $badClasses ) {
$testDetails [ 2 ] .= " . The following classes are at fault: " . implode ( ', ' , $badClasses );
$this -> error ( $testDetails );
}
else return true ;
}
2008-11-22 04:36:31 +01:00
function requirePHPVersion ( $recommendedVersion , $requiredVersion , $testDetails ) {
$this -> testing ( $testDetails );
list ( $recA , $recB , $recC ) = explode ( '.' , $recommendedVersion );
list ( $reqA , $reqB , $reqC ) = explode ( '.' , $requiredVersion );
list ( $a , $b , $c ) = explode ( '.' , phpversion ());
$c = ereg_replace ( '-.*$' , '' , $c );
if ( $a > $recA || ( $a == $recA && $b > $recB ) || ( $a == $reqA && $b == $reqB && $c >= $reqC )) {
$testDetails [ 2 ] = " SilverStripe recommends PHP version $recommendedVersion or later, only $a . $b . $c is installed. While SilverStripe should run, you may run into issues, and future versions of SilverStripe may require a later version. Upgrading PHP is recommended. " ;
$this -> warning ( $testDetails );
return ;
}
if ( $a > $reqA ) return true ;
if ( $a == $reqA && $b > $reqB ) return true ;
if ( $a == $reqA && $b == $reqB && $c >= $reqC ) return true ;
if ( ! $testDetails [ 2 ]) {
if ( $a < $reqA ) {
$testDetails [ 2 ] = " You need PHP version $version or later, only $a . $b . $c is installed. Unfortunately PHP $a and PHP $reqA have some incompatabilities, so if you are on a your web-host may need to move you to a different server. Some software doesn't work with PHP5 and so upgrading a shared server could be problematic. " ;
} else {
$testDetails [ 2 ] = " You need PHP version $requiredVersion or later, only $a . $b . $c is installed. Please upgrade your server, or ask your web-host to do so. " ;
}
}
$this -> error ( $testDetails );
}
function requireFile ( $filename , $testDetails ) {
$this -> testing ( $testDetails );
$filename = $this -> getBaseDir () . $filename ;
if ( ! file_exists ( $filename )) {
$testDetails [ 2 ] .= " (file ' $filename ' not found) " ;
$this -> error ( $testDetails );
}
}
function requireNoFile ( $filename , $testDetails ) {
$this -> testing ( $testDetails );
$filename = $this -> getBaseDir () . $filename ;
if ( file_exists ( $filename )) {
$testDetails [ 2 ] .= " (file ' $filename ' found) " ;
$this -> error ( $testDetails );
}
}
function moveFileOutOfTheWay ( $filename , $testDetails ) {
$this -> testing ( $testDetails );
$filename = $this -> getBaseDir () . $filename ;
if ( file_exists ( $filename )) {
if ( file_exists ( " $filename .bak " )) rm ( " $filename .bak " );
rename ( $filename , " $filename .bak " );
}
}
function requireWriteable ( $filename , $testDetails ) {
$this -> testing ( $testDetails );
$filename = $this -> getBaseDir () . str_replace ( " / " , DIRECTORY_SEPARATOR , $filename );
if ( ! is_writeable ( $filename )) {
if ( function_exists ( 'posix_getgroups' )) {
$userID = posix_geteuid ();
$user = posix_getpwuid ( $userID );
$currentOwnerID = fileowner ( $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 ();
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 \n For example: \n chmod 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 );
}
}
function requireTempFolder ( $testDetails ) {
$this -> testing ( $testDetails );
if ( function_exists ( 'sys_get_temp_dir' )) {
$sysTmp = sys_get_temp_dir ();
} elseif ( isset ( $_ENV [ 'TMP' ])) {
$sysTmp = $_ENV [ 'TMP' ];
} else {
@ $tmpFile = tempnam ( 'adfadsfdas' , '' );
@ unlink ( $tmpFile );
$sysTmp = dirname ( $tmpFile );
}
$worked = true ;
$ssTmp = " $sysTmp /silverstripe-cache " ;
if ( !@ file_exists ( $ssTmp )) {
@ $worked = mkdir ( $ssTmp );
if ( ! $worked ) {
$ssTmp = dirname ( $_SERVER [ 'SCRIPT_FILENAME' ]) . " /silverstripe-cache " ;
$worked = true ;
if ( !@ file_exists ( $ssTmp )) {
@ $worked = mkdir ( $ssTmp );
}
if ( ! $worked ) {
$testDetails [ 2 ] = " 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 adequate permissions " ;
$this -> error ( $testDetails );
}
}
}
}
function requireApacheModule ( $moduleName , $testDetails ) {
$this -> testing ( $testDetails );
if ( ! in_array ( $moduleName , apache_get_modules ())) $this -> error ( $testDetails );
}
function requireMysqlConnection ( $server , $username , $password , $testDetails ) {
$this -> testing ( $testDetails );
$conn = @ mysql_connect ( $server , $username , $password );
if ( $conn ) {
return true ;
/*
if ( mysql_query ( " CREATE DATABASE testing123 " )) {
mysql_query ( " DROP DATABASE testing123 " );
return true ;
} else {
$testDetails [ 2 ] .= " (user ' $username ' doesn't have CREATE DATABASE permissions.) " ;
$this -> error ( $testDetails );
}
*/
} else {
$testDetails [ 2 ] .= " : " . mysql_error ();
$this -> error ( $testDetails );
}
}
function requireMySQLServer ( $server , $testDetails ) {
$this -> testing ( $testDetails );
$conn = @ mysql_connect ( $server , null , null );
if ( $conn || mysql_errno () < 2000 ) {
return true ;
} else {
$testDetails [ 2 ] .= " : " . mysql_error ();
$this -> error ( $testDetails );
}
}
function requireMySQLVersion ( $version , $testDetails ) {
$this -> testing ( $testDetails );
if ( ! mysql_get_server_info ()) {
$testDetails [ 2 ] = 'Cannot determine the version of MySQL installed. Please ensure at least version 4.1 is installed.' ;
$this -> warning ( $testDetails );
} else {
list ( $majorRequested , $minorRequested ) = explode ( '.' , $version );
$result = mysql_query ( 'SELECT VERSION()' );
$row = mysql_fetch_row ( $result );
$version = ereg_replace ( " ([A-Za-z-]) " , " " , $row [ 0 ]);
list ( $majorHas , $minorHas ) = explode ( '.' , substr ( trim ( $version ), 0 , 3 ));
if (( $majorHas > $majorRequested ) || ( $majorHas == $majorRequested && $minorHas >= $minorRequested )) {
return true ;
} else {
$testDetails [ 2 ] .= " { $majorHas } . { $minorHas } . " ;
$this -> error ( $testDetails );
}
}
}
function requireDatabaseOrCreatePermissions ( $server , $username , $password , $database , $testDetails ) {
$this -> testing ( $testDetails );
$conn = @ mysql_connect ( $server , $username , $password );
if ( @ mysql_select_db ( $database )) {
$okay = " Database ' $database ' exists " ;
} else {
if ( @ mysql_query ( " CREATE DATABASE testing123 " )) {
mysql_query ( " DROP DATABASE testing123 " );
$okay = " Able to create a new database " ;
} else {
$testDetails [ 2 ] .= " (user ' $username ' doesn't have CREATE DATABASE permissions.) " ;
$this -> error ( $testDetails );
return ;
}
}
if ( $okay ) {
$testDetails [ 3 ] = $okay ;
$this -> testing ( $testDetails );
}
}
function requireServerVariables ( $varNames , $errorMessage ) {
//$this->testing($testDetails);
foreach ( $varNames as $varName ) {
if ( ! $_SERVER [ $varName ]) $missing [] = '$_SERVER[' . $varName . ']' ;
}
if ( ! isset ( $missing )) {
return true ;
} else {
$testDetails [ 2 ] .= " (the following PHP variables are missing: " . implode ( " , " , $missing ) . " ) " ;
$this -> error ( $testDetails );
}
}
function isRunningApache ( $testDetails ) {
$this -> testing ( $testDetails );
if ( function_exists ( 'apache_get_modules' ) || stristr ( $_SERVER [ 'SERVER_SIGNATURE' ], 'Apache' ))
return true ;
$this -> warning ( $testDetails );
return false ;
}
protected $baseDir ;
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 ;
}
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 );
}
function error ( $testDetails ) {
$section = $testDetails [ 0 ];
$test = $testDetails [ 1 ];
$this -> tests [ $section ][ $test ] = array ( " error " , $testDetails [ 2 ]);
$this -> errors [] = $testDetails ;
}
function warning ( $testDetails ) {
$section = $testDetails [ 0 ];
$test = $testDetails [ 1 ];
$this -> tests [ $section ][ $test ] = array ( " warning " , $testDetails [ 2 ]);
$this -> warnings [] = $testDetails ;
}
function hasErrors () {
return sizeof ( $this -> errors );
}
function hasWarnings () {
return sizeof ( $this -> warnings );
}
}
class Installer extends InstallRequirements {
function __construct () {
// Cache the baseDir value
$this -> getBaseDir ();
}
function install ( $config ) {
if ( isset ( $_SERVER [ 'HTTP_HOST' ])) {
?>
< h1 > Installing SilverStripe ...</ h1 >
< 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
< ? php
} else {
echo " SILVERSTRIPE COMMAND-LINE INSTALLATION \n \n " ;
}
flush ();
if ( isset ( $_POST [ 'stats' ])) {
if ( file_exists ( 'sapphire/silverstripe_version' )) {
$sapphireVersionFile = file_get_contents ( 'sapphire/silverstripe_version' );
if ( strstr ( $sapphireVersionFile , " /sapphire/trunk " )) {
$silverstripe_version = " trunk " ;
} else {
preg_match ( " /sapphire \ /(?:(?:branches)|(?:tags))(?: \ /rc)? \ /([A-Za-z0-9._-]+) \ /silverstripe_version/ " , $sapphireVersionFile , $matches );
$silverstripe_version = $matches [ 1 ];
}
} else {
$silverstripe_version = " unknown " ;
}
$phpVersion = urlencode ( phpversion ());
$conn = @ mysql_connect ( $config [ 'mysql' ][ 'server' ], null , null );
$databaseVersion = urlencode ( 'MySQL ' . mysql_get_server_info ());
$webserver = urlencode ( $_SERVER [ 'SERVER_SOFTWARE' ]);
$url = " http://ss2stat.silverstripe.com/Installation/add?SilverStripe= $silverstripe_version &PHP= $phpVersion &Database= $databaseVersion &WebServer= $webserver " ;
if ( isset ( $_SESSION [ 'StatsID' ]) && $_SESSION [ 'StatsID' ]) {
$url .= '&ID=' . $_SESSION [ 'StatsID' ];
}
@ $_SESSION [ 'StatsID' ] = file_get_contents ( $url );
}
if ( file_exists ( 'mysite/_config.php' )) {
unlink ( 'mysite/_config.php' );
}
$theme = isset ( $_POST [ 'template' ]) ? $_POST [ 'template' ] : 'blackcandy' ;
// Write the config file
global $usingEnv ;
if ( $usingEnv ) {
$this -> statusMessage ( " Creating 'mysite/_config.php' for use with _ss_environment.php... " );
$this -> createFile ( " mysite/_config.php " , <<< PHP
< ? php
global \ $project ;
\ $project = 'mysite' ;
global \ $database ;
\ $database = " { $config [ 'mysql' ][ 'database' ] } " ;
require_once ( " conf/ConfigureFromEnv.php " );
2009-06-28 22:37:22 +02:00
MySQLDatabase :: set_connection_charset ( 'utf8' );
2008-11-22 04:36:31 +01:00
// This line set's the current theme. More themes can be
2009-11-05 04:08:41 +01:00
// downloaded from http://www.silverstripe.org/themes/
2008-11-22 04:36:31 +01:00
SSViewer :: set_theme ( '$theme' );
2009-10-11 02:46:16 +02:00
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree :: enable_nested_urls ();
2008-11-22 04:36:31 +01:00
PHP
);
} else {
$this -> statusMessage ( " Creating 'mysite/_config.php'... " );
$devServers = $this -> var_export_array_nokeys ( explode ( " \n " , $_POST [ 'devsites' ]));
$escapedPassword = addslashes ( $config [ 'mysql' ][ 'password' ]);
$this -> createFile ( " mysite/_config.php " , <<< PHP
< ? php
global \ $project ;
\ $project = 'mysite' ;
global \ $databaseConfig ;
\ $databaseConfig = array (
" type " => " $config[database] " ,
" server " => " { $config [ 'mysql' ][ 'server' ] } " ,
" username " => " { $config [ 'mysql' ][ 'username' ] } " ,
2009-11-05 03:57:12 +01:00
" password " => '{$escapedPassword}' ,
2008-11-22 04:36:31 +01:00
" database " => " { $config [ 'mysql' ][ 'database' ] } " ,
);
// Sites running on the following servers will be
// run in development mode. See
2009-11-05 04:08:41 +01:00
// http://doc.silverstripe.org/doku.php?id=configuration
2008-11-22 04:36:31 +01:00
// for a description of what dev mode does.
Director :: set_dev_servers ( $devServers );
// This line set's the current theme. More themes can be
2009-11-05 04:08:41 +01:00
// downloaded from http://www.silverstripe.org/themes/
2008-11-22 04:36:31 +01:00
SSViewer :: set_theme ( '$theme' );
2009-10-11 02:46:16 +02:00
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree :: enable_nested_urls ();
2008-11-22 04:36:31 +01:00
PHP
);
}
$this -> statusMessage ( " Creating '.htaccess' file... " );
$this -> createHtaccess ();
// Load the sapphire runtime
$_SERVER [ 'SCRIPT_FILENAME' ] = dirname ( realpath ( $_SERVER [ 'SCRIPT_FILENAME' ])) . '/sapphire/main.php' ;
chdir ( 'sapphire' );
2009-11-19 21:29:42 +01:00
// Rebuild the manifest
2008-11-22 04:36:31 +01:00
$_GET [ 'flush' ] = true ;
2009-11-19 21:29:42 +01:00
// Show errors as if you're in development mode
$_SESSION [ 'isDev' ] = 1 ;
2008-11-22 04:36:31 +01:00
require_once ( 'core/Core.php' );
$this -> statusMessage ( " Building database schema... " );
// Build database
$con = new Controller ();
$con -> pushCurrent ();
global $databaseConfig ;
DB :: connect ( $databaseConfig );
$dbAdmin = new DatabaseAdmin ();
$dbAdmin -> init ();
$_REQUEST [ 'username' ] = $config [ 'admin' ][ 'username' ];
$_REQUEST [ 'password' ] = $config [ 'admin' ][ 'password' ];
$dbAdmin -> doBuild ( true );
2008-11-23 01:30:52 +01:00
$adminmember = DataObject :: get_one ( 'Member' , " \" Email \" = ' " . $_REQUEST [ 'admin' ][ 'username' ] . " ' " );
2008-11-22 04:36:31 +01:00
if ( $adminmember ) {
$adminmember -> FirstName = $_REQUEST [ 'admin' ][ 'firstname' ];
$adminmember -> Surname = $_REQUEST [ 'admin' ][ 'surname' ];
$adminmember -> write ();
}
// Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266)
FileSystem :: sync ();
if ( isset ( $_SERVER [ 'HTTP_HOST' ])) {
$this -> statusMessage ( " Checking mod_rewrite works... " );
$modRewriteWorks = $this -> checkModRewrite ();
} else {
$modRewriteWorks = true ;
}
$_SESSION [ 'username' ] = $config [ 'admin' ][ 'username' ];
$_SESSION [ 'password' ] = $config [ 'admin' ][ 'password' ];
if ( $modRewriteWorks && ! $this -> errors ) {
if ( isset ( $_SERVER [ 'HTTP_HOST' ])) {
echo " <p>Installed SilverStripe successfully. I will now try and direct you to
< a href = \ " home/successfullyinstalled?flush=1 \" >home/successfullyinstalled</a> to confirm that the installation was successful.</p>
< script > setTimeout ( function () { window . location . href = 'home/successfullyinstalled?flush=1' ; }, 1000 ); </ script >
" ;
} else {
echo " \n SilverStripe successfully installed \n " ;
}
}
return $this -> errors ;
}
function makeFolder ( $folder ) {
$base = $this -> getBaseDir ();
if ( ! file_exists ( $base . $folder )) {
if ( ! mkdir ( $base . $folder , 02775 )) {
$this -> error ( " Couldn't create a folder called $base $folder " );
} else {
chmod ( $base . $folder , 02775 );
}
}
}
function renameFolder ( $oldName , $newName ) {
if ( $oldName == $newName ) return true ;
$base = $this -> getBaseDir ();
if ( ! rename ( $base . $oldName , $base . $newName )) {
$this -> error ( " Couldn't rename $base $oldName to $base $newName " );
return false ;
} else {
return true ;
}
}
function copyFolder ( $oldName , $newName ) {
if ( $oldName == $newName ) return true ;
$base = $this -> getBaseDir ();
if ( ! copyr ( $base . $oldName , $base . $newName )) {
$this -> error ( " Couldn't rename $base $oldName to $base $newName " );
return false ;
} else {
return true ;
}
}
function createFile ( $filename , $content ) {
$base = $this -> getBaseDir ();
$this -> statusMessage ( " Creating $base $filename " );
if (( @ $fh = fopen ( $base . $filename , 'w' )) && fwrite ( $fh , $content ) && fclose ( $fh )) {
return true ;
} else {
$this -> error ( " Couldn't write to file $base $filename " );
}
}
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 = " " ;
$rewrite = <<< TEXT
< IfModule mod_dir . c >
DirectorySlash Off
</ IfModule >
< Files *. ss >
Order deny , allow
Deny from all
Allow from 127.0 . 0.1
</ Files >
RewriteEngine On
$baseClause
2009-07-15 01:57:21 +02:00
RewriteCond % { REQUEST_URI } ! ( \ . gif $ ) | ( \ . jpg $ ) | ( \ . png $ ) | ( \ . css $ ) | ( \ . js $ )
2008-11-22 04:36:31 +01:00
RewriteCond % { REQUEST_URI } ^ ( .* ) $
RewriteCond % { REQUEST_FILENAME } !- f
RewriteRule .* sapphire / main . php ? url =% 1 &% { QUERY_STRING } [ L ]
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 -> createFile ( '.htaccess' , $start . $rewrite . $end );
}
function createHtaccessAlternative () {
$start = " ### SILVERSTRIPE START ### \n " ;
$end = " \n ### SILVERSTRIPE END ### " ;
$base = dirname ( $_SERVER [ 'SCRIPT_NAME' ]);
if ( $base != '.' ) $baseClause = " RewriteBase $base\n " ;
$rewrite = <<< TEXT
< IfModule mod_dir . c >
DirectorySlash Off
</ IfModule >
< Files *. ss >
Order deny , allow
Deny from all
Allow from 127.0 . 0.1
</ Files >
RewriteEngine On
$baseClause
2009-07-15 01:57:21 +02:00
RewriteCond % { REQUEST_URI } ! ( \ . gif $ ) | ( \ . jpg $ ) | ( \ . png $ ) | ( \ . css $ ) | ( \ . js $ )
2008-11-22 04:36:31 +01:00
RewriteCond % { REQUEST_URI } ^ ( .* ) $
RewriteCond % { REQUEST_FILENAME } !- f
RewriteRule .* $_SERVER [ DOCUMENT_ROOT ] / sapphire / main . php ? url =% 1 &% { QUERY_STRING } [ L ]
TEXT ;
if ( file_exists ( $this -> getBaseDir () . '.htaccess' )) {
$htaccess = file_get_contents ( $this -> getBaseDir () . '.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 ###' ));
}
}
echo " \n \n Rewrite is $rewrite\n " ;
$this -> createFile ( '.htaccess' , $start . $rewrite . $end );
}
function restoreHtaccess () {
$start = " ### SILVERSTRIPE START ### \n " ;
$end = " \n ### SILVERSTRIPE END ### " ;
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 -> createFile ( '.htaccess' , $start . $end );
}
function checkModRewrite () {
if ( $this -> performModRewriteTest () == true ) {
return true ;
}
$this -> createHtaccessAlternative ();
if ( $this -> performModRewriteTest () == false ) {
echo " <li>ERROR: mod_rewrite not working, redirecting to mod_rewrite test page</li> " ;
$this -> restoreHtaccess ();
echo " I will now try and direct you to <a href= \" rewritetest.php \" >rewritetest</a> to troubleshoot mod_rewrite</p>
< script > setTimeout ( function () { window . location . href = 'rewritetest.php' ; }, 1000 ); </ script >
" ;
return false ;
}
return true ;
}
function performModRewriteTest () {
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. " );
return true ;
}
$baseURL = dirname ( $_SERVER [ 'SCRIPT_NAME' ]);
if ( $baseURL == " / " ) {
$baseURL = " " ;
}
// Check if mod_rewrite works properly
$location = 'http://' . ( isset ( $_SERVER [ 'PHP_AUTH_USER' ]) ? " $_SERVER[PHP_AUTH_USER] : $_SERVER[PHP_AUTH_PW] @ " : '' ) . $_SERVER [ 'HTTP_HOST' ] . $baseURL . '/InstallerTest/testrewrite' ;
echo $location ;
@ $testrewriting = file_get_contents ( $location );
if ( $testrewriting == 'OK' ) {
return true ;
}
// Workaround for 'URL file-access is disabled in the server configuration' using curl
if ( function_exists ( 'curl_init' )) {
$ch = curl_init ( $location );
$fp = @ fopen ( dirname ( tempnam ( 'adfadsfdas' , '' )) . '/rewritetest' , " w " );
if ( $fp ) {
curl_setopt ( $ch , CURLOPT_FILE , $fp );
curl_setopt ( $ch , CURLOPT_HEADER , 0 );
curl_exec ( $ch );
curl_close ( $ch );
fclose ( $fp );
$testrewriting = file_get_contents ( dirname ( tempnam ( 'adfadsfdas' , '' )) . '/rewritetest' );
unlink ( dirname ( tempnam ( 'adfadsfdas' , '' )) . '/rewritetest' );
if ( $testrewriting == 'OK' ) {
return true ;
}
}
}
return false ;
}
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
*/
function statusMessage ( $msg ) {
if ( isset ( $_SERVER [ 'HTTP_HOST' ])) echo " <li> $msg </li> \n " ;
else echo " $msg\n " ;
flush ();
}
}
/**
* Copy a file , or recursively copy a folder and its contents
*
* @ author Aidan Lister < aidan @ php . net >
* @ version 1.0 . 1
* @ link http :// aidanlister . com / repos / v / function . copyr . php
* @ param string $source Source path
* @ param string $dest Destination path
* @ return bool Returns TRUE on success , FALSE on failure
*/
function copyr ( $source , $dest )
{
// Simple copy for a file
if ( is_file ( $source )) {
return copy ( $source , $dest );
}
// Make destination directory
if ( ! is_dir ( $dest )) {
mkdir ( $dest );
}
// Loop through the folder
$dir = dir ( $source );
while ( false !== $entry = $dir -> read ()) {
// Skip pointers
if ( $entry == '.' || $entry == '..' ) {
continue ;
}
// Deep copy directories
if ( $dest !== " $source / $entry " ) {
copyr ( " $source / $entry " , " $dest / $entry " );
}
}
// Clean up
$dir -> close ();
return true ;
}
function rm ( $fileglob )
{
if ( is_string ( $fileglob )) {
if ( is_file ( $fileglob )) {
return unlink ( $fileglob );
} else if ( is_dir ( $fileglob )) {
$ok = rm ( " $fileglob /* " );
if ( ! $ok ) {
return false ;
}
return rmdir ( $fileglob );
} else {
$matching = glob ( $fileglob );
if ( $matching === false ) {
trigger_error ( sprintf ( 'No files match supplied glob %s' , $fileglob ), E_USER_WARNING );
return false ;
}
$rcs = array_map ( 'rm' , $matching );
if ( in_array ( false , $rcs )) {
return false ;
}
}
} else if ( is_array ( $fileglob )) {
$rcs = array_map ( 'rm' , $fileglob );
if ( in_array ( false , $rcs )) {
return false ;
}
} else {
trigger_error ( 'Param #1 must be filename or glob pattern, or array of filenames or glob patterns' , E_USER_ERROR );
return false ;
}
return true ;
}
?>