require_once 'core/startup/ErrorControlChain.php'; require_once 'core/startup/ParameterConfirmationToken.php'; // Prepare tokens and execute chain $reloadToken = ParameterConfirmationToken::prepare_tokens(array('isTest', 'isDev', 'flush')); $chain = new ErrorControlChain(); $chain->then(function ($chain) use($reloadToken) { // If no redirection is necessary then we can disable error supression if (!$reloadToken) { $chain->setSuppression(false); } // Load in core require_once 'core/Core.php'; // Connect to database global $databaseConfig; if ($databaseConfig) { DB::connect($databaseConfig); } // Check if a token is requesting a redirect if (!$reloadToken) { return; } // Otherwise, we start up the session if needed if (!isset($_SESSION) && Session::request_contains_session_id()) { Session::start(); } // Next, check if we're in dev mode, or the database doesn't have any security data, or we are admin if (Director::isDev() || !Security::database_is_ready() || Permission::check('ADMIN')) { return $reloadToken->reloadWithToken(); } // Fail and redirect the user to the login page $loginPage = Director::absoluteURL(Security::config()->login_url);
/** * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages * @param boolean $populate Populate the database, as well as setting up its schema * @param bool $testMode */ public function doBuild($quiet = false, $populate = true, $testMode = false) { if ($quiet) { DB::quiet(); } else { $conn = DB::get_conn(); // Assumes database class is like "MySQLDatabase" or "MSSQLDatabase" (suffixed with "Database") $dbType = substr(get_class($conn), 0, -8); $dbVersion = $conn->getVersion(); $databaseName = method_exists($conn, 'currentDatabase') ? $conn->getSelectedDatabase() : ""; if (Director::is_cli()) { echo sprintf("\n\nBuilding database %s using %s %s\n\n", $databaseName, $dbType, $dbVersion); } else { echo sprintf("<h2>Building database %s using %s %s</h2>", $databaseName, $dbType, $dbVersion); } } // Set up the initial database if (!DB::is_active()) { if (!$quiet) { echo '<p><b>Creating database</b></p>'; } // Load parameters from existing configuration global $databaseConfig; if (empty($databaseConfig) && empty($_REQUEST['db'])) { user_error("No database configuration available", E_USER_ERROR); } $parameters = !empty($databaseConfig) ? $databaseConfig : $_REQUEST['db']; // Check database name is given if (empty($parameters['database'])) { user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR); } $database = $parameters['database']; // Establish connection and create database in two steps unset($parameters['database']); DB::connect($parameters); DB::create_database($database); } // Build the database. Most of the hard work is handled by DataObject $dataClasses = ClassInfo::subclassesFor('SilverStripe\\ORM\\DataObject'); array_shift($dataClasses); if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE TABLES\n\n"; } else { echo "\n<p><b>Creating database tables</b></p>\n\n"; } } // Initiate schema update $dbSchema = DB::get_schema(); $dbSchema->schemaUpdate(function () use($dataClasses, $testMode, $quiet) { foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if (!class_exists($dataClass)) { continue; } // Check if this class should be excluded as per testing conventions $SNG = singleton($dataClass); if (!$testMode && $SNG instanceof TestOnly) { continue; } // Log data if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } // Instruct the class to apply its schema to the database $SNG->requireTable(); } }); ClassInfo::reset_db_cache(); if ($populate) { if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE RECORDS\n\n"; } else { echo "\n<p><b>Creating database records</b></p>\n\n"; } } foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness // Test_ indicates that it's the data class is part of testing system if (strpos($dataClass, 'Test_') === false && class_exists($dataClass)) { if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } singleton($dataClass)->requireDefaultRecords(); } } // Remap obsolete class names $schema = DataObject::getSchema(); foreach ($this->config()->classname_value_remapping as $oldClassName => $newClassName) { $badRecordCount = $newClassName::get()->filter(["ClassName" => $oldClassName])->count(); if ($badRecordCount > 0) { if (Director::is_cli()) { echo " * Correcting {$badRecordCount} obsolete classname values for {$newClassName}\n"; } else { echo "<li>Correcting {$badRecordCount} obsolete classname values for {$newClassName}</li>\n"; } $table = $schema->baseDataTable($newClassName); DB::prepared_query("UPDATE \"{$table}\" SET \"ClassName\" = ? WHERE \"ClassName\" = ?", [$newClassName, $oldClassName]); } } } touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder())); if (isset($_REQUEST['from_installer'])) { echo "OK"; } if (!$quiet) { echo Director::is_cli() ? "\n Database build completed!\n\n" : "<p>Database build completed!</p>"; } ClassInfo::reset_db_cache(); }
public static function create_temp_db() { // Disable PHPUnit error handling restore_error_handler(); // Create a temporary database, and force the connection to use UTC for time global $databaseConfig; $databaseConfig['timezone'] = '+0:00'; DB::connect($databaseConfig); $dbConn = DB::get_conn(); $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; $dbname = strtolower(sprintf('%stmpdb', $prefix)) . rand(1000000, 9999999); while (!$dbname || $dbConn->databaseExists($dbname)) { $dbname = strtolower(sprintf('%stmpdb', $prefix)) . rand(1000000, 9999999); } $dbConn->selectDatabase($dbname, true); $st = Injector::inst()->create('SapphireTest'); $st->resetDBSchema(); // Reinstate PHPUnit error handling set_error_handler(array('PHPUnit_Util_ErrorHandler', 'handleError')); return $dbname; }
public function install($config) { ?> <html> <head> <meta charset="utf-8"/> <title>Installing SilverStripe...</title> <link rel="stylesheet" type="text/css" href="<?php echo FRAMEWORK_NAME; ?> /src/Dev/Install/client/dist/styles/install.css"/> <script src="//code.jquery.com/jquery-1.7.2.min.js"></script> </head> <body> <div class="install-header"> <div class="inner"> <div class="brand"> <span class="logo"></span> <h1>SilverStripe</h1> </div> </div> </div> <div id="Navigation"> </div> <div class="clear"><!-- --></div> <div class="main"> <div class="inner"> <h2>Installing SilverStripe...</h2> <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> <ul> <?php $webserver = $this->findWebserver(); $isIIS = $this->isIIS(); $isApache = $this->isApache(); flush(); if (isset($config['stats'])) { if (file_exists(FRAMEWORK_NAME . '/silverstripe_version')) { $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version'); } else { $silverstripe_version = "unknown"; } $phpVersion = urlencode(phpversion()); $encWebserver = urlencode($webserver); $dbType = $config['db']['type']; // Try to determine the database version from the helper $databaseVersion = $config['db']['type']; $helper = $this->getDatabaseConfigurationHelper($dbType); if ($helper && method_exists($helper, 'getDatabaseVersion')) { $versionConfig = $config['db'][$dbType]; $versionConfig['type'] = $dbType; $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($versionConfig)); } $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe={$silverstripe_version}&PHP={$phpVersion}&Database={$databaseVersion}&WebServer={$encWebserver}"; if (isset($_SESSION['StatsID']) && $_SESSION['StatsID']) { $url .= '&ID=' . $_SESSION['StatsID']; } @($_SESSION['StatsID'] = file_get_contents($url)); } if (file_exists('mysite/_config.php')) { // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them $fh = fopen('mysite/_config.php', 'wb'); fclose($fh); } // Escape user input for safe insertion into PHP file $theme = isset($_POST['template']) ? addcslashes($_POST['template'], "\\'") : 'simple'; $locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\\'") : 'en_US'; $type = addcslashes($config['db']['type'], "\\'"); $dbConfig = $config['db'][$type]; $dbConfig = array_map(create_function('$v', 'return addcslashes($v, "\\\'");'), $dbConfig); if (!isset($dbConfig['path'])) { $dbConfig['path'] = ''; } if (!$dbConfig) { echo "<p style=\"color: red\">Bad config submitted</p><pre>"; print_r($config); echo "</pre>"; die; } // Write the config file global $usingEnv; if ($usingEnv) { $this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php..."); $this->writeToFile("mysite/_config.php", <<<PHP <?php global \$project; \$project = 'mysite'; global \$database; \$database = '{$dbConfig['database']}'; require_once('conf/ConfigureFromEnv.php'); PHP ); } else { $this->statusMessage("Setting up 'mysite/_config.php'..."); // Create databaseConfig $lines = array($lines[] = "\t'type' => '{$type}'"); foreach ($dbConfig as $key => $value) { $lines[] = "\t'{$key}' => '{$value}'"; } $databaseConfigContent = implode(",\n", $lines); $this->writeToFile("mysite/_config.php", <<<PHP <?php global \$project; \$project = 'mysite'; global \$databaseConfig; \$databaseConfig = array( {$databaseConfigContent} ); PHP ); } $this->statusMessage("Setting up 'mysite/_config/config.yml'"); $this->writeToFile("mysite/_config/config.yml", <<<YML --- Name: mysite After: - 'framework/*' - 'cms/*' --- # YAML configuration for SilverStripe # See http://doc.silverstripe.org/framework/en/topics/configuration # Caution: Indentation through two spaces, not tabs SilverStripe\\View\\SSViewer: themes: - '{$theme}' - '\$default' SilverStripe\\i18n\\i18n: default_locale: '{$locale}' YML ); if (!$this->checkModuleExists('cms')) { $this->writeToFile("mysite/code/RootURLController.php", <<<PHP <?php use SilverStripe\\Control\\Controller; class RootURLController extends Controller { \tpublic function index() { \t\techo "<html>Your site is now set up. Start adding controllers to mysite to get started.</html>"; \t} } PHP ); } // Write the appropriate web server configuration file for rewriting support if ($this->hasRewritingCapability()) { if ($isApache) { $this->statusMessage("Setting up '.htaccess' file..."); $this->createHtaccess(); } elseif ($isIIS) { $this->statusMessage("Setting up 'web.config' file..."); $this->createWebConfig(); } } // Load the SilverStripe runtime $_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/' . FRAMEWORK_NAME . '/main.php'; chdir(FRAMEWORK_NAME); // Rebuild the manifest $_GET['flush'] = true; // Show errors as if you're in development mode $_SESSION['isDev'] = 1; $this->statusMessage("Building database schema..."); require_once 'Core/Core.php'; // Build database $con = new Controller(); $con->pushCurrent(); global $databaseConfig; DB::connect($databaseConfig); $dbAdmin = new DatabaseAdmin(); $dbAdmin->doInit(); $dbAdmin->doBuild(true); // Create default administrator user and group in database // (not using Security::setDefaultAdmin()) $adminMember = Security::findAnAdministrator(); $adminMember->Email = $config['admin']['username']; $adminMember->Password = $config['admin']['password']; $adminMember->PasswordEncryption = Security::config()->encryption_algorithm; try { $this->statusMessage('Creating default CMS admin account...'); $adminMember->write(); } catch (Exception $e) { $this->statusMessage(sprintf('Warning: Default CMS admin account could not be created (error: %s)', $e->getMessage())); } $_SESSION['username'] = $config['admin']['username']; $_SESSION['password'] = $config['admin']['password']; if (!$this->errors) { if (isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) { $this->statusMessage("Checking that friendly URLs work..."); $this->checkRewrite(); } else { require_once 'Core/Startup/ParameterConfirmationToken.php'; $token = new ParameterConfirmationToken('flush'); $params = http_build_query($token->params()); $destinationURL = 'index.php/' . ($this->checkModuleExists('cms') ? "home/successfullyinstalled?{$params}" : "?{$params}"); echo <<<HTML \t\t\t\t<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li> \t\t\t\t<script> \t\t\t\t\tsetTimeout(function() { \t\t\t\t\t\twindow.location = "{$destinationURL}"; \t\t\t\t\t}, 2000); \t\t\t\t</script> \t\t\t\t<noscript> \t\t\t\t<li><a href="{$destinationURL}">Click here to access your site.</a></li> \t\t\t\t</noscript> HTML; } } return $this->errors; }