'Afrikaans (South Africa)', 'ar_EG' => 'Arabic (Egypt)', 'hy_AM' => 'Armenian (Armenia)', 'ast_ES' => 'Asturian (Spain)', 'az_AZ' => 'Azerbaijani (Azerbaijan)', 'bs_BA' => 'Bosnian (Bosnia and Herzegovina)', 'bg_BG' => 'Bulgarian (Bulgaria)', 'ca_ES' => 'Catalan (Spain)', 'zh_CN' => 'Chinese (China)', 'zh_TW' => 'Chinese (Taiwan)', 'hr_HR' => 'Croatian (Croatia)', 'cs_CZ' => 'Czech (Czech Republic)', 'da_DK' => 'Danish (Denmark)', 'nl_NL' => 'Dutch (Netherlands)', 'en_GB' => 'English (United Kingdom)', 'en_US' => 'English (United States)', 'eo_XX' => 'Esperanto', 'et_EE' => 'Estonian (Estonia)', 'fo_FO' => 'Faroese (Faroe Islands)', 'fi_FI' => 'Finnish (Finland)', 'fr_FR' => 'French (France)', 'de_DE' => 'German (Germany)', 'el_GR' => 'Greek (Greece)', 'he_IL' => 'Hebrew (Israel)', 'hu_HU' => 'Hungarian (Hungary)', 'is_IS' => 'Icelandic (Iceland)', 'id_ID' => 'Indonesian (Indonesia)', 'it_IT' => 'Italian (Italy)', 'ja_JP' => 'Japanese (Japan)', 'km_KH' => 'Khmer (Cambodia)', 'lc_XX' => 'LOLCAT', 'lv_LV' => 'Latvian (Latvia)', 'lt_LT' => 'Lithuanian (Lithuania)', 'ms_MY' => 'Malay (Malaysia)', 'mi_NZ' => 'Maori (New Zealand)', 'ne_NP' => 'Nepali (Nepal)', 'nb_NO' => 'Norwegian', 'fa_IR' => 'Persian (Iran)', 'pl_PL' => 'Polish (Poland)', 'pt_BR' => 'Portuguese (Brazil)', 'pa_IN' => 'Punjabi (India)', 'ro_RO' => 'Romanian (Romania)', 'ru_RU' => 'Russian (Russia)', 'sr_RS' => 'Serbian (Serbia)', 'si_LK' => 'Sinhalese (Sri Lanka)', 'sk_SK' => 'Slovak (Slovakia)', 'sl_SI' => 'Slovenian (Slovenia)', 'es_AR' => 'Spanish (Argentina)', 'es_MX' => 'Spanish (Mexico)', 'es_ES' => 'Spanish (Spain)', 'sv_SE' => 'Swedish (Sweden)', 'th_TH' => 'Thai (Thailand)', 'tr_TR' => 'Turkish (Turkey)', 'uk_UA' => 'Ukrainian (Ukraine)', 'uz_UZ' => 'Uzbek (Uzbekistan)', 'vi_VN' => 'Vietnamese (Vietnam)', ); // Discover which databases are available DatabaseAdapterRegistry::autodiscover(); // Determine which external database modules are USABLE foreach(DatabaseAdapterRegistry::get_adapters() as $class => $details) { $databaseClasses[$class] = $details; if(file_exists($details['helperPath'])) { $databaseClasses[$class]['hasModule'] = true; include_once($details['helperPath']); } else { $databaseClasses[$class]['hasModule'] = false; } } // Load database config if(isset($_REQUEST['db'])) { if(isset($_REQUEST['db']['type'])) $type = $_REQUEST['db']['type']; else $type = $_REQUEST['db']['type'] = defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase'; // Disabled inputs don't submit anything - we need to use the environment (except the database name) if($usingEnv) { $_REQUEST['db'][$type] = $databaseConfig = array( "type" => defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : $type, "server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost", "username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root", "password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "", "database" => $_REQUEST['db'][$type]['database'], ); } else { // Normal behaviour without the environment $databaseConfig = $_REQUEST['db'][$type]; $databaseConfig['type'] = $type; } } else { $type = $_REQUEST['db']['type'] = defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase'; $_REQUEST['db'][$type] = $databaseConfig = array( "type" => $type, "server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost", "username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root", "password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "", "database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite", ); } if(isset($_REQUEST['admin'])) { // Disabled inputs don't submit anything - we need to use the environment (except the database name) if($usingEnv) { $_REQUEST['admin'] = $adminConfig = array( 'username' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin', 'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? SS_DEFAULT_ADMIN_PASSWORD : '', ); } else { $adminConfig = $_REQUEST['admin']; } } else { $_REQUEST['admin'] = $adminConfig = array( 'username' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin', 'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? SS_DEFAULT_ADMIN_PASSWORD : '', ); } $alreadyInstalled = false; if(file_exists('mysite/_config.php')) { // Find the $database variable in the relevant config file without having to execute the config file if(preg_match("/\\\$database\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) { eval($parts[0]); if($database) $alreadyInstalled = true; // Assume that if $databaseConfig is defined in mysite/_config.php, then a non-environment-based installation has // already gone ahead } else if(preg_match("/\\\$databaseConfig\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) { $alreadyInstalled = true; } } if(file_exists(FRAMEWORK_NAME . '/silverstripe_version')) { $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version'); } else { $silverstripe_version = "unknown"; } // Check requirements $req = new InstallRequirements(); $req->check(); $webserverConfigFile = ''; if($req->isIIS()) { $webserverConfigFile = 'web.config'; } else { $webserverConfigFile = '.htaccess'; } if($req->hasErrors()) { $hasErrorOtherThanDatabase = true; $phpIniLocation = php_ini_loaded_file(); } if($databaseConfig) { $dbReq = new InstallRequirements(); $dbReq->checkDatabase($databaseConfig); } if($adminConfig) { $adminReq = new InstallRequirements(); $adminReq->checkAdminConfig($adminConfig); } // Actual processor $installFromCli = (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == 'install'); // CLI-install error message. exit(1) will halt any makefile. if($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) { echo "Cannot install due to errors:\n"; $req->listErrors(); $dbReq->listErrors(); exit(1); } if((isset($_REQUEST['go']) || $installFromCli) && !$req->hasErrors() && !$dbReq->hasErrors() && $adminConfig['username'] && $adminConfig['password']) { // Confirm before reinstalling if(!$installFromCli && $alreadyInstalled) { include(FRAMEWORK_NAME . '/dev/install/config-form.html'); } else { $inst = new Installer(); if($_REQUEST) $inst->install($_REQUEST); else $inst->install(array( 'db' => $databaseConfig, 'admin' => $adminConfig, )); } // Show the config form } else { include(FRAMEWORK_NAME . '/dev/install/config-form.html'); } /** * This class checks requirements * Each of the requireXXX functions takes an argument which gives a user description of the test. * It's an array of 3 parts: * $description[0] - The test catetgory * $description[1] - The test title * $description[2] - The test error to show, if it goes wrong */ class InstallRequirements { var $errors, $warnings, $tests; /** * Check the database configuration. These are done one after another * starting with checking the database function exists in PHP, and * continuing onto more difficult checks like database permissions. */ function checkDatabase($databaseConfig) { if($this->requireDatabaseFunctions( $databaseConfig, array( "Database Configuration", "Database support", "Database support in PHP", $this->getDatabaseTypeNice($databaseConfig['type']) ) )) { if($this->requireDatabaseServer( $databaseConfig, array( "Database Configuration", "Database server", $databaseConfig['type'] == 'SQLiteDatabase' ? "I couldn't write to path '$databaseConfig[path]'" : "I couldn't find a database server on '$databaseConfig[server]'", $databaseConfig['type'] == 'SQLiteDatabase' ? $databaseConfig['path'] : $databaseConfig['server'] ) )) { if($this->requireDatabaseConnection( $databaseConfig, array( "Database Configuration", "Database access credentials", "That username/password doesn't work" ) )) { if($this->requireDatabaseVersion( $databaseConfig, array( "Database Configuration", "Database server version requirement", '', 'Version ' . $this->getDatabaseConfigurationHelper($databaseConfig['type'])->getDatabaseVersion($databaseConfig) ) )) { if($this->requireDatabaseOrCreatePermissions( $databaseConfig, array( "Database Configuration", "Can I access/create the database", "I can't create new databases and the database '$databaseConfig[database]' doesn't exist" ) )) { $this->requireDatabaseAlterPermissions( $databaseConfig, array( "Database Configuration", "Can I ALTER tables", "I don't have permission to ALTER tables" ) ); } } } } } } function checkAdminConfig($adminConfig) { if(!$adminConfig['username']) { $this->error(array('', 'Please enter a username!')); } if(!$adminConfig['password']) { $this->error(array('', 'Please enter a password!')); } } /** * Check if the web server is IIS. * @return boolean */ function isIIS($version = 7) { if(strpos($this->findWebserver(), 'IIS/' . $version) !== false) { return true; } else { return false; } } function isApache() { if(strpos($this->findWebserver(), 'Apache') !== false) { return true; } else { return false; } } /** * Find the webserver software running on the PHP host. * @return string|boolean Server software or boolean FALSE */ function findWebserver() { // Try finding from SERVER_SIGNATURE or SERVER_SOFTWARE $webserver = @$_SERVER['SERVER_SIGNATURE']; if(!$webserver) $webserver = @$_SERVER['SERVER_SOFTWARE']; if($webserver) return strip_tags(trim($webserver)); else return false; } /** * Check everything except the database */ function check() { $this->errors = null; $isApache = $this->isApache(); $isIIS = $this->isIIS(7); $webserver = $this->findWebserver(); $this->requirePHPVersion('5.3.4', '5.3.2', array("PHP Configuration", "PHP5 installed", null, "PHP version " . phpversion())); // Check that we can identify the root folder successfully $this->requireFile(FRAMEWORK_NAME . '/dev/install/config-form.html', array("File permissions", "Does the webserver know where files are stored?", "The webserver isn't letting me identify where files are stored.", $this->getBaseDir() )); $this->requireModule('mysite', array("File permissions", "mysite/ directory exists?")); $this->requireModule(FRAMEWORK_NAME, array("File permissions", FRAMEWORK_NAME . "/ directory exists?")); if($isApache) { $this->checkApacheVersion(array("Webserver Configuration", "Webserver is not Apache 1.x", "SilverStripe requires Apache version 2 or greater", $webserver)); $this->requireWriteable('.htaccess', array("File permissions", "Is the .htaccess file writeable?", null)); } elseif($isIIS) { $this->requireWriteable('web.config', array("File permissions", "Is the web.config file writeable?", null)); } $this->requireWriteable('mysite/_config.php', array("File permissions", "Is the mysite/_config.php file writeable?", null)); if (!$this->checkModuleExists('cms')) { $this->requireWriteable('mysite/code/RootURLController.php', array("File permissions", "Is the mysite/code/RootURLController.php file writeable?", null)); } $this->requireWriteable('assets', array("File permissions", "Is the assets/ directory writeable?", null)); $tempFolder = $this->getTempFolder(); $this->requireTempFolder(array('File permissions', 'Is a temporary directory available?', null, $tempFolder)); if($tempFolder) { // in addition to the temp folder being available, check it is writable $this->requireWriteable($tempFolder, array("File permissions", sprintf("Is the temporary directory writeable?", $tempFolder), null), true); } // Check for web server, unless we're calling the installer from the command-line $this->isRunningWebServer(array("Webserver Configuration", "Server software", "Unknown", $webserver)); if($isApache) { $this->requireApacheRewriteModule('mod_rewrite', array("Webserver Configuration", "URL rewriting support", "You need mod_rewrite to use friendly URLs with SilverStripe, but it is not enabled.")); } elseif($isIIS) { $this->requireIISRewriteModule('IIS_UrlRewriteModule', array("Webserver Configuration", "URL rewriting support", "You need to enable the IIS URL Rewrite Module to use friendly URLs with SilverStripe, but it is not installed or enabled. Download it for IIS 7 from http://www.iis.net/expand/URLRewrite")); } else { $this->warning(array("Webserver Configuration", "URL rewriting support", "I can't tell whether any rewriting module is running. You may need to configure a rewriting rule yourself.")); } $this->requireServerVariables(array('SCRIPT_NAME','HTTP_HOST','SCRIPT_FILENAME'), array("Webserver Configuration", "Recognised webserver", "You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set.")); $this->requirePostSupport(array("Webserver Configuration", "POST Support", 'I can\'t find $_POST, make sure POST is enabled.')); // Check for GD support if(!$this->requireFunction("imagecreatetruecolor", array("PHP Configuration", "GD2 support", "PHP must have GD version 2."))) { $this->requireFunction("imagecreate", array("PHP Configuration", "GD2 support", "GD support for PHP not included.")); } // Check for XML support $this->requireFunction('xml_set_object', array("PHP Configuration", "XML support", "XML support not included in PHP.")); $this->requireClass('DOMDocument', array("PHP Configuration", "DOM/XML support", "DOM/XML support not included in PHP.")); $this->requireFunction('simplexml_load_file', array('PHP Configuration', 'SimpleXML support', 'SimpleXML support not included in PHP.')); // Check for token_get_all $this->requireFunction('token_get_all', array("PHP Configuration", "Tokenizer support", "Tokenizer support not included in PHP.")); // Check for CType support $this->requireFunction('ctype_digit', array('PHP Configuration', 'CType support', 'CType support not included in PHP.')); // Check for session support $this->requireFunction('session_start', array('PHP Configuration', 'Session support', 'Session support not included in PHP.')); // Check for iconv support $this->requireFunction('iconv', array('PHP Configuration', 'iconv support', 'iconv support not included in PHP.')); // Check for hash support $this->requireFunction('hash', array('PHP Configuration', 'hash support', 'hash support not included in PHP.')); // Check for mbstring support $this->requireFunction('mb_internal_encoding', array('PHP Configuration', 'mbstring support', 'mbstring support not included in PHP.')); // Check for Reflection support $this->requireClass('ReflectionClass', array('PHP Configuration', 'Reflection support', 'Reflection support not included in PHP.')); // Check for Standard PHP Library (SPL) support $this->requireFunction('spl_classes', array('PHP Configuration', 'SPL support', 'Standard PHP Library (SPL) not included in PHP.')); $this->requireDateTimezone(array('PHP Configuration', 'date.timezone setting and validity', 'date.timezone option in php.ini must be set correctly.', ini_get('date.timezone'))); $this->suggestClass('finfo', array('PHP Configuration', 'fileinfo support', 'fileinfo should be enabled in PHP. SilverStripe uses it for MIME type detection of files. SilverStripe will still operate, but email attachments and sending files to browser (e.g. export data to CSV) may not work correctly without finfo.')); $this->suggestFunction('curl_init', array('PHP Configuration', 'curl support', 'curl should be enabled in PHP. SilverStripe uses it for consuming web services via the RestfulService class and many modules rely on it.')); $this->suggestClass('tidy', array('PHP Configuration', 'tidy support', 'Tidy provides a library of code to clean up your html. SilverStripe will operate fine without tidy but HTMLCleaner will not be effective.')); $this->suggestPHPSetting('asp_tags', array(false), array('PHP Configuration', 'asp_tags option', 'This should be turned off as it can cause issues with SilverStripe')); $this->requirePHPSetting('magic_quotes_gpc', array(false), array('PHP Configuration', 'magic_quotes_gpc option', 'This should be turned off, as it can cause issues with cookies. More specifically, unserializing data stored in cookies.')); $this->suggestPHPSetting('display_errors', array(false), array('PHP Configuration', 'display_errors option', 'Unless you\'re in a development environment, this should be turned off, as it can expose sensitive data to website users.')); // Check memory allocation $this->requireMemory(32*1024*1024, 64*1024*1024, array("PHP Configuration", "Memory allocation (PHP config option 'memory_limit')", "SilverStripe needs a minimum of 32M allocated to PHP, but recommends 64M.", ini_get("memory_limit"))); return $this->errors; } 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 requirePHPSetting($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->error($testDetails); } } function suggestClass($class, $testDetails) { $this->testing($testDetails); if(!class_exists($class)) { $this->warning($testDetails); } } function suggestFunction($class, $testDetails) { $this->testing($testDetails); if(!function_exists($class)) { $this->warning($testDetails); } } function requireDateTimezone($testDetails) { $this->testing($testDetails); $result = ini_get('date.timezone') && in_array(ini_get('date.timezone'), timezone_identifiers_list()); if(!$result) { $this->error($testDetails); } } function requireMemory($min, $recommended, $testDetails) { $_SESSION['forcemem'] = false; $mem = $this->getPHPMemory(); if($mem < (64 * 1024 * 1024)) { ini_set('memory_limit', '64M'); $mem = $this->getPHPMemory(); $testDetails[3] = ini_get("memory_limit"); } $this->testing($testDetails); if($mem < $min && $mem > 0) { $testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated"; $this->error($testDetails); } else if($mem < $recommended && $mem > 0) { $testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated"; $this->warning($testDetails); } elseif($mem == 0) { $testDetails[2] .= " We can't determine how much memory you have allocated. Install only if you're sure you've allocated at least 20 MB."; $this->warning($testDetails); } } function getPHPMemory() { $memString = ini_get("memory_limit"); switch(strtolower(substr($memString,-1))) { case "k": return round(substr($memString,0,-1)*1024); case "m": return round(substr($memString,0,-1)*1024*1024); case "g": return round(substr($memString,0,-1)*1024*1024*1024); default: return round($memString); } } function listErrors() { if($this->errors) { echo "

The following problems are preventing me from installing SilverStripe CMS:

\n\n"; foreach($this->errors as $error) { echo "
  • " . htmlentities(implode(", ", $error), ENT_COMPAT, 'UTF-8') . "
  • \n"; } } } function showTable($section = null) { if($section) { $tests = $this->tests[$section]; $id = strtolower(str_replace(' ', '_', $section)); echo ""; foreach($tests as $test => $result) { echo ""; } echo "
    $test" . nl2br(htmlentities($result[1], ENT_COMPAT, 'UTF-8')) . "
    "; } else { foreach($this->tests as $section => $tests) { $failedRequirements = 0; $warningRequirements = 0; $output = ""; foreach($tests as $test => $result) { if(isset($result['0'])) { switch($result['0']) { case 'error': $failedRequirements++; break; case 'warning': $warningRequirements++; break; } } $output .= "$test" . nl2br(htmlentities($result[1], ENT_COMPAT, 'UTF-8')) . ""; } $className = "good"; $text = "All Requirements Pass"; $pluralWarnings = ($warningRequirements == 1) ? 'Warning' : 'Warnings'; if($failedRequirements > 0) { $className = "error"; $pluralWarnings = ($warningRequirements == 1) ? 'Warning' : 'Warnings'; $text = $failedRequirements . ' Failed and '. $warningRequirements . ' '. $pluralWarnings; } else if($warningRequirements > 0) { $className = "warning"; $text = "All Requirements Pass but ". $warningRequirements . ' '. $pluralWarnings; } echo "
    $section Show All Requirements $text
    "; echo ""; echo $output; echo "
    "; } } } function requireFunction($funcName, $testDetails) { $this->testing($testDetails); if(!function_exists($funcName)) { $this->error($testDetails); } else return true; } function requireClass($className, $testDetails) { $this->testing($testDetails); if(!class_exists($className)) $this->error($testDetails); else return false; } /** * 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; } function checkApacheVersion($testDetails) { $this->testing($testDetails); $is1pointx = preg_match('#Apache[/ ]1\.#', $testDetails[3]); if($is1pointx) { $this->error($testDetails); } return true; } function requirePHPVersion($recommendedVersion, $requiredVersion, $testDetails) { $this->testing($testDetails); $installedVersion = phpversion(); if(version_compare($installedVersion, $requiredVersion, '<')) { $testDetails[2] = "SilverStripe requires PHP version $requiredVersion or later.\n PHP version $installedVersion is currently installed.\n While SilverStripe requires at least PHP version $requiredVersion, upgrading to $recommendedVersion or later is recommended.\n If you are installing SilverStripe on a shared web server, please ask your web hosting provider to upgrade PHP for you."; $this->error($testDetails); return; } if(version_compare($installedVersion, $recommendedVersion, '<')) { $testDetails[2] = "PHP version $installedVersion is currently installed.\n Upgrading to at least PHP version $recommendedVersion is recommended.\n SilverStripe should run, but you may run into issues. Future releases may require a later version of PHP.\n"; $this->warning($testDetails); return; } return true; } /** * Check that a module exists */ function checkModuleExists($dirname) { $path = $this->getBaseDir() . $dirname; return file_exists($path) && ($dirname == 'mysite' || file_exists($path . '/_config.php')); } /** * The same as {@link requireFile()} but does additional checks * to ensure the module directory is intact. */ function requireModule($dirname, $testDetails) { $this->testing($testDetails); $path = $this->getBaseDir() . $dirname; if(!file_exists($path)) { $testDetails[2] .= " Directory '$path' not found. Please make sure you have uploaded the SilverStripe files to your webserver correctly."; $this->error($testDetails); } elseif(!file_exists($path . '/_config.php') && $dirname != 'mysite') { $testDetails[2] .= " Directory '$path' exists, but is missing files. Please make sure you have uploaded the SilverStripe files to your webserver correctly."; $this->error($testDetails); } } 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 requireWriteable($filename, $testDetails, $absolute = false) { $this->testing($testDetails); if($absolute) { $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename); } else { $filename = $this->getBaseDir() . str_replace('/', DIRECTORY_SEPARATOR, $filename); } if(file_exists($filename)) $isWriteable = is_writeable($filename); else $isWriteable = is_writeable(dirname($filename)); if(!$isWriteable) { if(function_exists('posix_getgroups')) { $userID = posix_geteuid(); $user = posix_getpwuid($userID); $currentOwnerID = fileowner(file_exists($filename) ? $filename : dirname($filename) ); $currentOwner = posix_getpwuid($currentOwnerID); $testDetails[2] .= "User '$user[name]' needs to be able to write to this file:\n$filename\n\nThe file is currently owned by '$currentOwner[name]'. "; if($user['name'] == $currentOwner['name']) { $testDetails[2] .= "We recommend that you make the file writeable."; } else { $groups = posix_getgroups(); $groupList = array(); foreach($groups as $group) { $groupInfo = posix_getgrgid($group); if(in_array($currentOwner['name'], $groupInfo['members'])) $groupList[] = $groupInfo['name']; } if($groupList) { $testDetails[2] .= " We recommend that you make the file group-writeable and change the group to one of these groups:\n - ". implode("\n - ", $groupList) . "\n\nFor example:\nchmod g+w $filename\nchgrp " . $groupList[0] . " $filename"; } else { $testDetails[2] .= " There is no user-group that contains both the web-server user and the owner of this file. Change the ownership of the file, create a new group, or temporarily make the file writeable by everyone during the install process."; } } } else { $testDetails[2] .= "The webserver user needs to be able to write to this file:\n$filename"; } $this->error($testDetails); } } function getTempFolder() { $sysTmp = sys_get_temp_dir(); $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) return $ssTmp; return false; } function requireTempFolder($testDetails) { $this->testing($testDetails); $tempFolder = $this->getTempFolder(); if(!$tempFolder) { $testDetails[2] = "Permission problem gaining access to a temp directory. " . "Please create a folder named silverstripe-cache in the base directory " . "of the installation and ensure it has the adequate permissions."; $this->error($testDetails); } } function requireApacheModule($moduleName, $testDetails) { $this->testing($testDetails); if(!in_array($moduleName, apache_get_modules())) { $this->error($testDetails); return false; } else { return true; } } function testApacheRewriteExists($moduleName = 'mod_rewrite') { if(function_exists('apache_get_modules') && in_array($moduleName, apache_get_modules())) { return true; } elseif(isset($_SERVER['HTTP_MOD_REWRITE']) && $_SERVER['HTTP_MOD_REWRITE'] == 'On') { return true; } else { return false; } } function testIISRewriteModuleExists($moduleName = 'IIS_UrlRewriteModule') { if(isset($_SERVER[$moduleName]) && $_SERVER[$moduleName]) { return true; } else { return false; } } function requireApacheRewriteModule($moduleName, $testDetails) { $this->testing($testDetails); if($this->testApacheRewriteExists()) { return true; } else { $this->warning($testDetails); return false; } } /** * Determines if the web server has any rewriting capability. * @return boolean */ function hasRewritingCapability() { return ($this->testApacheRewriteExists() || $this->testIISRewriteModuleExists()); } function requireIISRewriteModule($moduleName, $testDetails) { $this->testing($testDetails); if($this->testIISRewriteModuleExists()) { return true; } else { $this->warning($testDetails); return false; } } function getDatabaseTypeNice($databaseClass) { return substr($databaseClass, 0, -8); } /** * Get an instance of a helper class for the specific database. * @param string $databaseClass e.g. MySQLDatabase or MSSQLDatabase */ function getDatabaseConfigurationHelper($databaseClass) { $adapters = DatabaseAdapterRegistry::get_adapters(); if(isset($adapters[$databaseClass])) { $helperPath = $adapters[$databaseClass]['helperPath']; $class = str_replace('.php', '', basename($helperPath)); } return (class_exists($class)) ? new $class() : new MySQLDatabaseConfigurationHelper(); } function requireDatabaseFunctions($databaseConfig, $testDetails) { $this->testing($testDetails); $helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']); $result = $helper->requireDatabaseFunctions($databaseConfig); if($result) { return true; } else { $this->error($testDetails); return false; } } function requireDatabaseConnection($databaseConfig, $testDetails) { $this->testing($testDetails); $helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']); $result = $helper->requireDatabaseConnection($databaseConfig); if($result['success']) { return true; } else { $testDetails[2] .= ": " . $result['error']; $this->error($testDetails); return false; } } function requireDatabaseVersion($databaseConfig, $testDetails) { $this->testing($testDetails); $helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']); if(method_exists($helper, 'requireDatabaseVersion')) { $result = $helper->requireDatabaseVersion($databaseConfig); if($result['success']) { return true; } else { $testDetails[2] .= $result['error']; $this->warning($testDetails); return false; } } // Skipped test because this database has no required version return true; } function requireDatabaseServer($databaseConfig, $testDetails) { $this->testing($testDetails); $helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']); $result = $helper->requireDatabaseServer($databaseConfig); if($result['success']) { return true; } else { $testDetails[2] .= ": " . $result['error']; $this->error($testDetails); return false; } } function requireDatabaseOrCreatePermissions($databaseConfig, $testDetails) { $this->testing($testDetails); $helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']); $result = $helper->requireDatabaseOrCreatePermissions($databaseConfig); if($result['success']) { if($result['alreadyExists']) $testDetails[3] = "Database $databaseConfig[database]"; else $testDetails[3] = "Able to create a new database"; $this->testing($testDetails); return true; } else { if(!@$result['cannotCreate']) { $testDetails[2] .= ". Please create the database manually."; } else { $testDetails[2] .= " (user '$databaseConfig[username]' doesn't have CREATE DATABASE permissions.)"; } $this->error($testDetails); return false; } } function requireDatabaseAlterPermissions($databaseConfig, $testDetails) { $this->testing($testDetails); $helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']); $result = $helper->requireDatabaseAlterPermissions($databaseConfig); if ($result['success']) { return true; } else { $testDetails[2] = "Silverstripe cannot alter tables. This won't prevent installation, however it may " . "cause issues if you try to run a /dev/build once installed."; $this->warning($testDetails); return; } } function requireServerVariables($varNames, $testDetails) { $this->testing($testDetails); $missing = array(); foreach($varNames as $varName) { if(!isset($_SERVER[$varName]) || !$_SERVER[$varName]) { $missing[] = '$_SERVER[' . $varName . ']'; } } if(!$missing) { return true; } else { $testDetails[2] .= " (the following PHP variables are missing: " . implode(", ", $missing) . ")"; $this->error($testDetails); } } function requirePostSupport($testDetails) { $this->testing($testDetails); if(!isset($_POST)) { $this->error($testDetails); return false; } return true; } function isRunningWebServer($testDetails) { $this->testing($testDetails); if($testDetails[3]) { return true; } else { $this->warning($testDetails); return false; } } // Must be PHP4 compatible var $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) { ?> Installing SilverStripe...

    SilverStripe

    Installing SilverStripe...

    I am now running through the installation steps (this should take about 30 seconds)

    If you receive a fatal error, refresh this page to continue the installation