MINOR Moved project

git-svn-id: http://svn.silverstripe.com/projects/ss2doc/branches/v2@108782 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2010-08-02 10:06:21 +00:00
commit aab89e65f8
40 changed files with 2349 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
sapphire/
cms/
src/
sapphiredocs/

19
.htaccess Normal file
View File

@ -0,0 +1,19 @@
### SILVERSTRIPE START ###
<Files *.ss>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Files>
<Files web.config>
Order deny,allow
Deny from all
</Files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* sapphire/main.php?url=%1&%{QUERY_STRING} [L]
</IfModule>
### SILVERSTRIPE END ###

8
.mergesources.yml Normal file
View File

@ -0,0 +1,8 @@
# Data source for the "arb" svn merge tool (see http://github.com/sminnee/arborist).
# Keeps track of all opensource branches of submodules
# that could be merged back to the current submodule paths.
trunk:
.: /open/phpinstaller/trunk
sapphire: /open/modules/sapphire/trunk
cms: /open/modules/cms/trunk
jsparty: /open/modules/jsparty/trunk

17
COPYING Normal file
View File

@ -0,0 +1,17 @@
Copyright (c) 2007-2008, SilverStripe Limited - www.silverstripe.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of SilverStripe nor the names of its contributors may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

1
ChangeLog Normal file
View File

@ -0,0 +1 @@
For a full change log, please visit http://open.silverstripe.org/wiki/ChangeLog.

19
INSTALL Normal file
View File

@ -0,0 +1,19 @@
Thanks for downloading SilverStripe CMS.
Simply extract the archive to a folder in a web-accessible location and visit the folder
in your web browser (which in turn runs index.php).
This will lead you through a web-based installation process.
Server Requirements
* PHP 5.0.4+ (5.2+ is recommended)
* MySQL 4.1+ (other databases are supported - details here: http://doc.silverstripe.com/doku.php?id=server-requirements)
* Apache or IIS 7.x
* More information on server requirements here: http://doc.silverstripe.com/doku.php?id=server-requirements
General documentation, tutorials:
* Wiki: http://doc.silverstripe.com/
* Tutorials: http://doc.silverstripe.org/doku.php?id=tutorials
Forum
* http://www.silverstripe.com/silverstripe-forum/

19
Makefile Normal file
View File

@ -0,0 +1,19 @@
#
# This makefile is a secondary way of installing SilverStripe.
# It is used for things like continuous integration
#
# Most users should simply visit the site root in your web browser.
#
test:
$(MAKE) QUERYSTRING="$(QUERYSTRING)" -C sapphire test
getallmodules:
if [ -d auth_openid ]; then svn update auth_openid; else svn co http://svn.silverstripe.com/open/modules/auth_openid/trunk auth_openid; fi
if [ -d blog ]; then svn update blog; else svn co http://svn.silverstripe.com/open/modules/blog/trunk blog; fi
if [ -d cmsworkflow ]; then svn update cmsworkflow; else svn co http://svn.silverstripe.com/open/modules/cmsworkflow/trunk cmsworkflow; fi
if [ -d forum ]; then svn update forum; else svn co http://svn.silverstripe.com/open/modules/forum/trunk forum; fi
if [ -d genericdataadmin ]; then svn update genericdataadmin; else svn co http://svn.silverstripe.com/open/modules/genericdataadmin/trunk genericdataadmin; fi
if [ -d multiform ]; then svn update multiform; else svn co http://svn.silverstripe.com/open/modules/multiform/trunk multiform; fi
if [ -d subsites ]; then svn update subsites; else svn co http://svn.silverstripe.com/open/modules/subsites/trunk subsites; fi
if [ -d userforms ]; then svn update userforms; else svn co http://svn.silverstripe.com/open/modules/userforms/trunk userforms; fi

20
UPGRADING Normal file
View File

@ -0,0 +1,20 @@
Usually upgrading your SilverStripe installation just means overwriting files
and updating your database-schema.
- Backup your database
- Backup your webroot
- Download the new release and uncompress it to a temporary folder
- With these folders: cms, sapphire, googlesitemaps
- Delete your existing folders
- Extract and replace folders from your download (leave modules
and your custom directories alone)
- Moving your current folders (rather than installing on top) means
you can undo the installation, and ensures if the new release has no
longer contains some files, these files won't be left behind, which otherwise
could cause bugs.
- Visit http://your.silverstripe.site/dev/build (This adds new
fields/tables to the database, and empties your template cache)
- Check if any modules (e.g. blog or forum) in your installation are compatible
and need to be upgraded as well
- Check if you need to adapt your code to changed APIs, see
http://doc.silverstripe.com/doku.php?id=upgrading

2
assets/.htaccess Normal file
View File

@ -0,0 +1,2 @@
RemoveHandler .php .phtml .php3 .php4 .php5 .inc
RemoveType .php .phtml .php3 .php4 .php5 .inc

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

63
index.php Normal file
View File

@ -0,0 +1,63 @@
<?php
/************************************************************************************
************************************************************************************
** **
** 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. **
** **
************************************************************************************
************************************************************************************/
/**
* This script bolts on top of SilverStripe/Sapphire to allow access without the use of .htaccess
* rewriting rules.
*/
// This is the URL of the script that everything must be viewed with.
define('BASE_SCRIPT_URL','index.php/');
$ruLen = strlen($_SERVER['REQUEST_URI']);
$snLen = strlen($_SERVER['SCRIPT_NAME']);
$isIIS = (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false);
// IIS will populate server variables using one of these two ways
if($isIIS) {
if($_SERVER['REQUEST_URI'] == $_SERVER['SCRIPT_NAME']) {
$url = "";
} else if($ruLen > $snLen && substr($_SERVER['REQUEST_URI'],0,$snLen+1) == ($_SERVER['SCRIPT_NAME'] . '/')) {
$url = substr($_SERVER['REQUEST_URI'],$snLen+1);
$url = strtok($url, '?');
} else {
$url = $_SERVER['REQUEST_URI'];
if($url[0] == '/') $url = substr($url,1);
$url = strtok($url, '?');
}
// Apache will populate the server variables this way
} else {
if($ruLen > $snLen && substr($_SERVER['REQUEST_URI'],0,$snLen+1) == ($_SERVER['SCRIPT_NAME'] . '/')) {
$url = substr($_SERVER['REQUEST_URI'],$snLen+1);
$url = strtok($url, '?');
} else {
$url = "";
}
}
$_GET['url'] = $_REQUEST['url'] = $url;
$fileName = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . $url;
/**
* This code is a very simple wrapper for sending files
* Very quickly pass through references to files
*/
if($url && file_exists($fileName)) {
$fileURL = (dirname($_SERVER['SCRIPT_NAME'])=='/'?'':dirname($_SERVER['SCRIPT_NAME'])) . '/' . $url;
header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently');
header("Location: $fileURL");
die();
}
require_once('sapphire/main.php');

1250
install.php Normal file
View File

@ -0,0 +1,1250 @@
<?php
/************************************************************************************
************************************************************************************
** **
** 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. **
** **
************************************************************************************
************************************************************************************/
/**
* SilverStripe CMS Installer
* This installer doesn't use any of the fancy Sapphire stuff in case it's unsupported.
* It's also PHP4 syntax compatable
*/
// speed up mysql_connect timeout if the server can't be found
ini_set('mysql.connect_timeout', 5);
ini_set('max_execution_time', 0);
error_reporting(E_ALL ^ E_NOTICE);
session_start();
$majorVersion = strtok(phpversion(),'.');
if($majorVersion < 5) {
header("HTTP/1.1 500 Server Error");
echo str_replace('$PHPVersion', phpversion(), file_get_contents("sapphire/dev/install/php5-required.html"));
die();
}
// Include environment files
$usingEnv = false;
$envFileExists = false;
$envFiles = array('_ss_environment.php', '../_ss_environment.php', '../../_ss_environment.php');
foreach($envFiles as $envFile) {
if(@file_exists($envFile)) {
include_once($envFile);
$envFileExists = true;
$usingEnv = true;
break;
}
}
if($envFileExists) {
if(!empty($_REQUEST['useEnv'])) {
$usingEnv = true;
} else {
$usingEnv = false;
}
}
include_once('sapphire/core/Object.php');
include_once('sapphire/core/i18n.php');
include_once('sapphire/dev/install/DatabaseConfigurationHelper.php');
include_once('sapphire/dev/install/DatabaseAdapterRegistry.php');
// Set default locale, but try and sniff from the user agent
$locales = i18n::$common_locales;
$defaultLocale = i18n::get_locale();
if(isset($_SERVER['HTTP_USER_AGENT'])) {
foreach($locales as $code => $details) {
$bits = explode('_', $code);
if(preg_match("/{$bits[0]}.{$bits[1]}/", $_SERVER['HTTP_USER_AGENT'])) {
$defaultLocale = $code;
break;
}
}
}
// Discover which databases are available
DatabaseAdapterRegistry::autodiscover();
// Determine which external database modules are USABLE
foreach(DatabaseAdapterRegistry::get_adapters() as $class => $details) {
$databaseClasses[$class] = $details;
if(file_exists($details['helperPath'])) {
$databaseClasses[$class]['hasModule'] = true;
include_once($details['helperPath']);
} else {
$databaseClasses[$class]['hasModule'] = false;
}
}
// Load database config
if(isset($_REQUEST['db'])) {
if(isset($_REQUEST['db']['type'])) $type = $_REQUEST['db']['type'];
else $type = $_REQUEST['db']['type'] = defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase';
// Disabled inputs don't submit anything - we need to use the environment (except the database name)
if($usingEnv) {
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : $type,
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "",
"database" => $_REQUEST['db'][$type]['database'],
);
} else {
// Normal behaviour without the environment
$databaseConfig = $_REQUEST['db'][$type];
$databaseConfig['type'] = $type;
}
} else {
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : "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'])) {
// 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('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();
$webserverConfigFile = '';
if($req->isIIS()) {
$webserverConfigFile = 'web.config';
} else {
$webserverConfigFile = '.htaccess';
}
if($req->hasErrors()) {
$hasErrorOtherThanDatabase = true;
}
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(!isset($_REQUEST['force_reinstall']) && !$installFromCli && $alreadyInstalled) {
include('sapphire/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('sapphire/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 not included in PHP.")
)
) {
if($this->requireDatabaseServer(
$databaseConfig,
array(
"Database Configuration",
"Database server exists",
"I couldn't find a database server on '$databaseConfig[server]'",
$databaseConfig['server']
)
)) {
if($this->requireDatabaseConnection(
$databaseConfig,
array(
"Database Configuration",
"Database access credentials correct",
"That username/password doesn't work"
)
)) {
if($this->requireDatabaseVersion(
$databaseConfig,
array(
"Database Configuration",
"Database server meets required version",
""
)
)) {
$this->requireDatabaseOrCreatePermissions(
$databaseConfig,
array(
"Database Configuration",
"Can I access/create the database",
"I can't create new databases and the database '$databaseConfig[database]' doesn't exist"
)
);
}
}
}
}
}
function checkAdminConfig($adminConfig) {
if(!$adminConfig['username']) {
$this->error(array('', 'Please enter a username!'));
}
if(!$adminConfig['password']) {
$this->error(array('', 'Please enter a password!'));
}
}
/**
* Check if the web server is IIS.
* @return boolean
*/
function isIIS() {
if(isset($_SERVER['SERVER_SOFTWARE'])) {
if(strpos($_SERVER['SERVER_SOFTWARE'], 'IIS/7') !== false) {
return true;
}
}
return false;
}
function isApache() {
$signature = !empty($_SERVER['SERVER_SIGNATURE'])
? $_SERVER['SERVER_SIGNATURE']
: @$_SERVER['SERVER_SOFTWARE'];
$signature = strip_tags(trim($signature));
if($signature && strpos($signature, 'Apache') !== false) {
return true;
} else {
return false;
}
}
function findWebserver() {
$webserver = strip_tags(trim(@$_SERVER['SERVER_SIGNATURE']));
if(!$webserver) {
if(isset($_SERVER['SERVER_SOFTWARE'])) {
if(strpos($_SERVER['SERVER_SOFTWARE'], 'IIS/7') !== false ||
strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
$webserver = $_SERVER['SERVER_SOFTWARE'];
}
} else {
$webserver = "I can't tell what webserver you are running";
}
}
return $webserver;
}
/**
* Check everything except the database
*/
function check() {
$this->errors = null;
$isApache = $this->isApache();
$isIIS = $this->isIIS();
$webserver = $this->findWebserver();
$this->requirePHPVersion('5.2.0', '5.1.0', array("PHP Configuration", "PHP5 installed", null, "PHP version " . phpversion()));
// Check that we can identify the root folder successfully
$this->requireFile('sapphire/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->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."));
if($isApache) {
$this->requireWriteable('.htaccess', array("File permissions", "Is the .htaccess file writeable?", null));
} elseif($isIIS) {
$this->requireWriteable('web.config', array("File permissions", "Is the web.config file writeable?", null));
}
$this->requireWriteable('mysite/_config.php', array("File permissions", "Is the mysite/_config.php file writeable?", null));
$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']) {
$this->isRunningWebServer(array("Webserver Configuration", "Server software", "Unknown web server", $webserver));
if($isApache) {
$this->requireApacheRewriteModule('mod_rewrite', array("Webserver Configuration", "URL rewriting support", "You need mod_rewrite to use friendly URLs with SilverStripe, but it is not enabled."));
} elseif($isIIS) {
$this->requireIISRewriteModule('IIS_UrlRewriteModule', array("Webserver Configuration", "URL rewriting support", "You need to enable the IIS URL Rewrite Module to use friendly URLs with SilverStripe, but it is not installed or enabled. Download it for IIS 7 from http://www.iis.net/expand/URLRewrite"));
} else {
$this->warning(array("Webserver Configuration", "URL rewriting support", "I can't tell whether any rewriting module is running. You may need to configure a rewriting rule yourself."));
}
$this->requireServerVariables(array('SCRIPT_NAME','HTTP_HOST','SCRIPT_FILENAME'), array("Webserver config", "Recognised webserver", "You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."));
}
// Check for GD support
if(!$this->requireFunction("imagecreatetruecolor", array("PHP Configuration", "GD2 support", "PHP must have GD version 2."))) {
$this->requireFunction("imagecreate", array("PHP Configuration", "GD2 support", "GD support for PHP not included."));
}
// Check for XML support
$this->requireFunction('xml_set_object', array("PHP Configuration", "XML support", "XML support not included in PHP."));
$this->requireClass('DOMDocument', array("PHP Configuration", "DOM/XML support", "DOM/XML support not included in PHP."));
// Check for token_get_all
$this->requireFunction('token_get_all', array("PHP Configuration", "PHP Tokenizer", "PHP tokenizer support not included in PHP."));
// Check memory allocation
$this->requireMemory(32*1024*1024, 64*1024*1024, array("PHP Configuration", "Memory allocated (PHP config option 'memory_limit')", "SilverStripe needs a minimum of 32M allocated to PHP, but recommends 64M.", ini_get("memory_limit")));
return $this->errors;
}
function suggestPHPSetting($settingName, $settingValues, $testDetails) {
$this->testing($testDetails);
$val = ini_get($settingName);
if(!in_array($val, $settingValues) && $val != $settingValues) {
$testDetails[2] = "$settingName is set to '$val' in php.ini. $testDetails[2]";
$this->warning($testDetails);
}
}
function 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];
$id = strtolower(str_replace(' ', '_', $section));
echo "<table id=\"{$id}_results\" 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) {
$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 .= "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
}
$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 "<h5 class='requirement $className'><em class='inlineBarText'>$section</em> <a href='#'>See All Requirements</a> <span>$text</span></h5>";
echo "<table class=\"testResults\">";
echo $output;
echo "</table>";
}
}
}
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 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;
}
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) {
$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\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 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);
return false;
} else {
return true;
}
}
function testApacheRewriteExists($moduleName = 'mod_rewrite') {
if(function_exists('apache_get_modules') && in_array($moduleName, apache_get_modules())) {
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;
}
}
/**
* 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] exists";
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 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 isRunningWebServer($testDetails) {
$this->testing($testDetails);
if(function_exists('apache_get_modules') || stristr(@$_SERVER['SERVER_SIGNATURE'], 'Apache')) {
return true;
} elseif(strpos($_SERVER['SERVER_SOFTWARE'], 'IIS/7') !== false) {
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) {
if(isset($_SERVER['HTTP_HOST'])) {
?>
<html>
<head>
<title>Installing SilverStripe...</title>
<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/form.css" />
<link rel="stylesheet" type="text/css" href="sapphire/dev/install/install.css" />
<script src="sapphire/thirdparty/jquery/jquery.js"></script>
</head>
<body>
<div id="BgContainer">
<div id="Container">
<div id="Header">
<h1>SilverStripe CMS Installation</h1>
</div>
<div id="Navigation">&nbsp;</div>
<div class="clear"><!-- --></div>
<div id="Layout">
<div class="typography">
<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</p>
<ul>
<?php
} else {
echo "SILVERSTRIPE COMMAND-LINE INSTALLATION\n\n";
}
$webserver = $this->findWebserver();
$isIIS = $this->isIIS();
$isApache = $this->isApache();
flush();
if(isset($config['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());
$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')) {
$databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($config['db'][$dbType]));
}
$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);
}
$theme = isset($_POST['template']) ? $_POST['template'] : 'blackcandy';
$locale = isset($_POST['locale']) ? $_POST['locale'] : 'en_US';
$type = $config['db']['type'];
$dbConfig = $config['db'][$type];
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');
MySQLDatabase::set_connection_charset('utf8');
// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme');
// Set the site locale
i18n::set_locale('$locale');
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();
PHP
);
} else {
$this->statusMessage("Setting up 'mysite/_config.php'...");
$escapedPassword = addslashes($dbConfig['password']);
$this->writeToFile("mysite/_config.php", <<<PHP
<?php
global \$project;
\$project = 'mysite';
global \$databaseConfig;
\$databaseConfig = array(
"type" => '{$type}',
"server" => '{$dbConfig['server']}',
"username" => '{$dbConfig['username']}',
"password" => '{$escapedPassword}',
"database" => '{$dbConfig['database']}',
"path" => '{$dbConfig['path']}',
);
// Sites running on the following servers will be
// run in development mode. See
// http://doc.silverstripe.org/doku.php?id=configuration
// for a description of what dev mode does.
Director::set_dev_servers(array(
'localhost',
'127.0.0.1'
));
MySQLDatabase::set_connection_charset('utf8');
// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme');
// Set the site locale
i18n::set_locale('$locale');
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();
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 sapphire runtime
$_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/sapphire/main.php';
chdir('sapphire');
// Rebuild the manifest
$_GET['flush'] = true;
// Show errors as if you're in development mode
$_SESSION['isDev'] = 1;
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();
$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::get_password_encryption_algorithm();
// @todo Exception thrown if database with admin already exists with same Email
try {
$adminMember->write();
} catch(Exception $e) {
}
// Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266)
Filesystem::sync();
$_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 {
echo <<<HTML
<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li>
<script>
setTimeout(function() {
window.location = "index.php/home/successfullyinstalled?flush=1";
}, 2000);
</script>
<noscript>
<li><a href="index.php/home/successfullyinstalled?flush=1">Click here to access your site.</li>
</noscript>
HTML;
}
}
return $this->errors;
}
function writeToFile($filename, $content) {
$base = $this->getBaseDir();
$this->statusMessage("Setting up $base$filename");
if((@$fh = fopen($base . $filename, 'wb')) && 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
<Files *.ss>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Files>
<Files web.config>
Order deny,allow
Deny from all
</Files>
<IfModule mod_rewrite.c>
RewriteEngine On
$baseClause
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* sapphire/main.php?url=%1&%{QUERY_STRING} [L]
</IfModule>
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->writeToFile('.htaccess', $start . $rewrite . $end);
}
/**
* Writes basic configuration to the web.config for IIS
* so that rewriting capability can be use.
*/
function createWebConfig() {
$content = <<<TEXT
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="SilverStripe Clean URLs" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="sapphire/main.php?url={R:1}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
TEXT;
$this->writeToFile('web.config', $content);
}
function checkRewrite() {
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;
}
echo <<<HTML
<li id="ModRewriteResult">Testing...</li>
<script>
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.";
setTimeout(function() {
window.location = "home/successfullyinstalled?flush=1";
}, 10000);
} else {
$.ajax({
method: 'get',
url: 'InstallerTest/testrewrite',
complete: function(response) {
if(response.responseText == 'OK') {
$('#ModRewriteResult').html("Friendly URLs set up successfully; I am now redirecting you to your SilverStripe site...")
setTimeout(function() {
window.location = "home/successfullyinstalled?flush=1";
}, 2000);
} else {
$('#ModRewriteResult').html("Friendly URLs are not working. This is most likely because a rewrite module isn't configured"
+ "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:"
+ "<ul><li>mod_rewrite is enabled</li><li>AllowOverride All is set for your directory</li></ul>");
}
}
});
}
</script>
<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>
</noscript>
HTML;
}
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();
}
}

34
mysite/_config.php Normal file
View File

@ -0,0 +1,34 @@
<?php
global $project;
$project = 'mysite';
global $database;
$database = 'SS_ssnewdocstest';
require_once('conf/ConfigureFromEnv.php');
MySQLDatabase::set_connection_charset('utf8');
// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('docs');
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();
// render the user documentation first
Director::addRules(20, array(
'Security//$Action/$ID/$OtherID' => 'Security',
));
DocumentationViewer::set_link_base('');
DocumentationViewer::$check_permission = false;
Director::addRules(10, array(
'$Action' => 'DocumentationViewer',
'' => '->current/en/cms'
));
DocumentationService::set_automatic_registration(false);
DocumentationService::register("cms", realpath("../src/github/master/cms/docs/"), '2.4');
// We want this to be reviewed by the whole community
BasicAuth::protect_entire_site(false);

41
mysite/code/Page.php Executable file
View File

@ -0,0 +1,41 @@
<?php
class Page extends SiteTree {
public static $db = array(
);
public static $has_one = array(
);
}
class Page_Controller extends ContentController {
/**
* An array of actions that can be accessed via a request. Each array element should be an action name, and the
* permissions or conditions required to allow the user to access it.
*
* <code>
* array (
* 'action', // anyone can access this action
* 'action' => true, // same as above
* 'action' => 'ADMIN', // you must have ADMIN permissions to access this action
* 'action' => '->checkAction' // you can only access this action if $this->checkAction() returns true
* );
* </code>
*
* @var array
*/
public static $allowed_actions = array (
);
public function init() {
parent::init();
// Note: you should use SS template require tags inside your templates
// instead of putting Requirements calls here. However these are
// included so that our older themes still work
Requirements::themedCSS('layout');
Requirements::themedCSS('typography');
Requirements::themedCSS('form');
}
}

60
scripts/pull-from-git Executable file
View File

@ -0,0 +1,60 @@
#!/bin/bash
#
# Pulls the documentation from our temp github repo and pulls it
# into the specific folders
#
# Usage ./scripts/pull-from-git
#
if [ `whoami` = "Will" ]; then
repo=git@github.com:willrossi/silverstripe-doc-restructuring.git
else
repo=git://github.com/willrossi/silverstripe-doc-restructuring.git
fi
scrpt=`dirname $0`
temp="docs"
# make sure that we're in the correct dir
cd $scrpt; cd ../
# clone the repo down, or update it if it already exists
if [ ! -d $temp ]; then
echo "Checking out documentation"
mkdir $temp
touch $temp/_manifest_exclude
git clone $repo $temp
else
# git pull must be performed in the folder with the checkout
echo "Updating documentation"
cd $temp
git pull
cd ../
fi
# remove the current docs if they exists.
# move it to a backup location because I know someone will
# make some changes to the docs and lose all their work
echo "Preparing folders"
if [ -d "cms/docs" ]; then
if [ -d "cms/docs_backup" ]; then
rm -rf cms/docs_backup
fi
mv cms/docs cms/docs_backup
fi
if [ -d "sapphire/docs" ]; then
if [ -d "sapphire/docs_backup" ]; then
rm -rf sapphire/docs_backup
fi
mv sapphire/docs sapphire/docs_backup
fi
echo "Moving files into place"
# copy the cms and sapphire docs to their correct locations
cp -R $temp/master/cms/docs cms/
cp -R $temp/master/sapphire/docs sapphire/
echo "Finished. Time for a beer."

View File

@ -0,0 +1,130 @@
/**
* Documentation Viewer Styles.
*
* @author Will Rossiter <will@silverstripe.com>
*/
/* Reset */
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{ margin:0;padding: 0;}
/* Core */
html { background: #f4f4f4;}
body { font: 14px/1.1 Arial,sans-serif; color: #444; }
a { color: #1389ce; text-decoration: none; }
a:hover,
a:focus { text-decoration: underline;}
p { font-size: 14px; line-height: 22px; margin-bottom: 22px; }
ul { margin: 11px 0 22px 20px; }
li { font-size: 12px; line-height: 13px; margin-bottom: 8px;}
h1 { font-size: 33px; line-height: 33px; margin-bottom: 22px; color: #111; letter-spacing: -1px;}
h2 { font-size: 24px; line-height: 33px; margin-bottom: 11px; color: #111; }
h3 { font-size: 18px; line-height: 22px; margin-bottom: 11px; color: #111; }
h4 { font-size: 16px; margin-bottom: 11px; line-height: 22px;}
h5 { font-size: 14px; line-height: 22px; margin-bottom: 11px;}
pre {
margin-bottom: 22px;
font-family:'Bitstream Vera Sans Mono',Monaco, 'Courier New', monospace;
background: #f4f4f4;
padding: 11px;
font-size: 11px;
}
/* Forms */
fieldset { border: none; }
/* Container */
#container { width: 960px; margin: 44px auto 22px auto; padding: 22px 30px; background: #fff; overflow: hidden;
-webkit-box-shadow: 0 0 20px #ccc; -moz-box-shadow: 0 0 20px #ccc;}
/* Header */
#header { padding: 11px 0 0 0; margin-bottom: 22px; }
#header h1 { margin-bottom: 0px; line-height: 33px;}
#header h1 a { text-decoration: none; font-size: 30px; color: #121929; letter-spacing: -1px;}
#header #breadcrumbs p { font-size: 11px; margin: 0 0 10px 0; color: #798D85;}
#header #breadcrumbs p a { color: #798D85;}
/* Language Bar */
#language { position: absolute; top: 12px; left: 50%; margin-left: -480px; width: 960px; }
#language label { float: left; width: 830px; line-height: 19px; text-align: right; font-size: 11px; color: #999;}
#language select { float: right; width: 120px;}
#language input.action { float: right; margin-top: 4px;}
/* Footer */
#footer { width: 960px; margin: 22px auto; }
#footer p { font-size: 11px; line-height: 11px; color: #798D85;}
#footer p a { color: #798D85;}
/* Content */
#layout { }
#content { }
/* Versions */
#versions-nav { background: #121929; margin: 0 0 44px; padding: 10px 0 0 10px; overflow: hidden;}
#versions-nav h2 { font-size: 11px; color: #fff; font-weight: normal; float: left; margin-right: 5px;}
#versions-nav ul { margin: 0; padding: 0; float: left;}
#versions-nav li { list-style: none; }
#versions-nav li a { display: block; float: left; margin-left: 4px; padding: 11px; font-size: 14px;}
#versions-nav li a.current { background: #fff;}
#left-column { width: 640px; float: left; }
#right-column {
width: 260px;
float: right;
}
#right-column .box {
margin: 0 12px 12px 0;
}
/* Nested tree */
.box ul.tree {}
.box ul.tree li {
list-style: none;
}
.box ul.tree li.folder {
background: #d5eefd;
font-size: 12px;
color: #29688c;
margin-bottom: 9px;
border: 1px solid #d5eefd;
padding: 2px 6px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
.undocumented-modules {
clear: both;
padding-top: 10px;
font-style: italic;
}
.module { margin: 10px -; }
/**
* TOC
*/
.sidebar-box {
margin: 0 0 11px 0;
padding: 11px 15px;
background: #f4f4f4;
width: 220px;
}
.sidebar-box ul { margin: 0; padding: 0;}
.sidebar-box h4 { font-size: 12px; margin-bottom: 11px;}
.sidebar-box ul li { list-style: none; }
.sidebar-box ul li .current { font-weight: bold;}
.sidebar-box ul li.h1 { margin-top: 11px; font-weight: bold;}
.sidebar-box ul li.h2,
.sidebar-box ul ul { margin-top: 8px;}
.sidebar-box ul li li { font-size: 11px; margin-left: 10px;}
.sidebar-box ul li.h3,
.sidebar-box ul li li li { margin-left: 20px; font-size: 10px; margin-left: 20px;}
.sidebar-box ul li.h4,
.sidebar-box ul li li li li { margin-right: 30px; font-size: 10px; margin-left: 20px; }

View File

@ -0,0 +1,36 @@
<div id="sidebar">
<% if Menu(2) %>
<ul id="sub-navigation">
<% control Menu(2) %>
<li class="$LinkingMode">
<a href="$Link">$MenuTitle</a>
<% if LinkOrSection = section %>
<% if Children %>
<ul>
<% control Children %>
<li class="$LinkingMode">
<a href="$Link">$MenuTitle</a>
<% if LinkOrSection = section %>
<% if Children %>
<ul>
<% control Children %>
<li class="$LinkingMode">
<a href="$Link">$MenuTitle</a>
</li>
<% end_control %>
</ul>
<% end_if %>
<% end_if %>
</li>
<% end_control %>
</ul>
<% end_if %>
<% end_if %>
</li>
<% end_control %>
</ul>
<% end_if %>
</div>

11
themes/docs/templates/Layout/Page.ss vendored Normal file
View File

@ -0,0 +1,11 @@
<% if Menu(2) %>
<% include Sidebar %>
<% end_if %>
<div id="content" class="<% if Menu(2) %>has-sidebar<% end_if %>">
<h2>$Title</h2>
$Content
$Form
$PageComments
</div>

View File

@ -0,0 +1,46 @@
<div class="typography">
<% if Results %>
<ul id="search-results">
<% control Results %>
<li>
<% if MenuTitle %>
<h3 class="search-results-header"><a href="$Link">$MenuTitle</a></h3>
<% else %>
<h3><a class="search-results-header" href="$Link">$Title</a></h3>
<% end_if %>
<% if Content %>
$Content.FirstParagraph(html)
<% end_if %>
<a class="read-more-link" href="$Link" title="Read more about &quot;{$Title}&quot;">Read more about &quot;{$Title}&quot;...</a>
</li>
<% end_control %>
</ul>
<% else %>
<p>Sorry, your search query did not return any results.</p>
<% end_if %>
<% if Results.MoreThanOnePage %>
<div id="page-numbers">
<% if Results.NotLastPage %>
<a class="next" href="$Results.NextLink" title="View the next page">Next</a>
<% end_if %>
<% if Results.NotFirstPage %>
<a class="prev" href="$Results.PrevLink" title="View the previous page">Prev</a>
<% end_if %>
<span>
<% control Results.SummaryPagination(5) %>
<% if CurrentBool %>
$PageNum
<% else %>
<a href="$Link" title="View page number $PageNum">$PageNum</a>
<% end_if %>
<% end_control %>
</span>
</div>
<% end_if %>
</div>

View File

@ -0,0 +1,6 @@
<div id="login-container">
<h2>$Title</h2>
$Content
$Form
</div>

53
themes/docs/templates/Page.ss vendored Normal file
View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<% base_tag %>
<title>$Title &raquo; $SiteConfig.Title</title>
$MetaTags(false)
<link rel="shortcut icon" href="favicon.ico">
<% require css(themes/ssorgsites/css/ss.all.min.css) %>
<% require css(themes/docs/css/documentation.css) %>
</head>
<body>
<div id="header">
<div id="logo">
<h1><a href="home/">$SiteConfig.Title</a></h1>
<p>$SiteConfig.Tagline</p>
</div>
<div id="search-form">
$SearchForm
</div>
</div>
<div id="navigation">
<ul>
<% control Menu(1) %>
<li class="$LinkingMode"><a href="$Link">$MenuTitle</a></li>
<% end_control %>
</ul>
</div>
<div id="layout" class="typography">
$Layout
</div>
<div class="clear"><!-- --></div>
<div id="footer">
<p class="left"><% _t('COPYRIGHT', 'Copyright') %> &copy; $Now.Year</p>
<p class="right">
<% if CurrentMember %>
<% _t('CURRENTLYONLINE', "You're currently logged in as") %> $CurrentMember.Name. <a href="Security/logout"><% _t('LOGOUT', 'Logout') %></a>
<% else_if RealPage %>
<% _t('CURRENTLYOFFNLINE', "You're currently not logged in") %>. <a href="Security/login"><% _t('LOGIN', 'Login') %></a>
<% end_if %>
</p>
</div>
</body>
</html>

View File

@ -0,0 +1,14 @@
/**
* This support file is used to style the WYSIWYG editor in the CMS
*/
@import "typography.css";
body.mceContentBody {
min-height: 200px;
font-size: 62.5%;
}
body.mceContentBody a.broken {
background-color: #FF7B71;
border: 1px red solid;
}

View File

@ -0,0 +1,64 @@
/* GENERIC FORM STYLING */
#Content form {
width:378px;
}
#Content form fieldset {
border:0;
padding:12px;
}
#Content .message {
color:red;
background:#ddd;
border:1px solid #ccc;
padding:5px;
margin:5px;
}
#Content span.message {
width: 300px;
}
#Content form div {
margin-top:10px;
width:100%;
}
#Content form label {
font-size:1.1em;
color:#333;
}
#Content form label.left {
float:left;
width:12em;
}
#Content form label.FormHeading {
font-size:1.3em;
color:#ff7200;
font-weight:bold;
}
#Content form input.text,
#Content form textarea,
#Content form select {
width:200px;
color:#000;
background:#f8f8f8;
border:1px solid #aaa;
padding:3px;
}
#Content form input.numeric {
width:20px;
background:#f0f0f0;
border:1px solid #aaa;
padding:3px;
color:#000;
margin-right:4px;
}
#Content form input.year {
width:35px;
}
#Content form p.Actions {
text-align:right;
padding:0 22px 15px 0;
}
#Content form p.Actions input {
padding:2px;
}

View File

@ -0,0 +1,287 @@
/* Global Resetting */
html{
width: 100%;
height: 100%;
background:url(../images/body_bg.gif) repeat;
}
body {
width: 100%;
height: 100%;
font-size: 62.5%;
/* reset font-sizes to 1em == 10px */
}
* {
font-size: 1em;
/* reset font-sizes to 1em == 10px */
padding: 0;
margin: 0;
font-family:Verdana,Helvetica,sans-serif;
list-style:none;
}
a img{
border:0;
}
.clear{
clear:both;
}
/* Layout CSS */
#Main {
margin:20px auto;
width:900px;
}
#Header {
background:url(../images/blueback.gif) bottom left repeat-x;
border-left:1px solid #ccc;
border-right:1px solid #ccc;
clear:left;
}
#Header h1 {
color:#fff;
font-size:1.5em;
line-height:4.5em;
padding-left:20px;
}
#Menu1 {
padding:10px 50px 0;
}
#Menu1 li {
float:left;
margin-left:2px;
background:url(../images/menu1_right.gif) no-repeat right top;
}
#Menu1 li.current,
#Menu1 li.section {
background:url(../images/menu1_right_on.gif) no-repeat right top;
}
#Menu1 li a {
display:block;
color:#fff;
font-weight:bold;
font-size:1.1em;
text-decoration:none;
padding:5px 15px;
background:url(../images/menu1_left.gif) no-repeat left top;
}
#Menu1 li a:hover {
color:#d2ebff;
}
#Menu1 li.current a,
#Menu1 li.section a {
background:url(../images/menu1_left_on.gif) no-repeat left top;
color:#d2ebff;
}
#ContentContainer {
background:#f5f5f5 url(../images/ss_watermark.gif) bottom left no-repeat;
padding-top:20px;
padding-bottom:20px;
overflow: auto;
}
#Banner {
text-align: center;
}
#Menu2 {
margin-left: 20px;
width: 17em;
float:left;
background:#f0f0f0;
border:1px solid #ddd;
padding:10px 10px 10px 10px;
}
#Menu2 li {
padding-left:15px;
background:url(../images/menu2_arrow.gif) no-repeat left center;
}
#Menu2 a {
color:#333;
font-weight:bold;
font-size:1.1em;
line-height:1.6em;
text-decoration:none;
}
#Menu2 a:hover {
text-decoration:underline;
}
#Menu2 li.current a,
#Menu2 li.section a {
color:#0083C8;
}
#Content {
float: left;
margin: 0px 20px;
width:70%;
}
div.breadcrumbs {
margin-bottom:10px;
font-size:1em;
color:#666;
}
div.breadcrumbs a {
text-decoration:none;
}
#Footer {
background:#015581;
clear:both;
text-align:right;
padding-right:20px;
border:1px solid #ccc;
border-top:0;
}
#Footer span {
color:#ccc;
font-size:1.1em;
line-height:2em;
font-weight:bold;
padding-left:20px;
background:url(../images/ss_logo.gif) no-repeat;
}
#Footer a {
color:#fff;
}
#Footer a:hover {
text-decoration:none;
}
/* The rest of this file is for the second tutorial */
#NewsList,
#StaffList {
background:#f0f0f0;
border:1px dotted #ccc;
padding:10px;
}
#NewsList li,
#StaffList li {
margin: 0;
list-style-type: none;
}
#NewsList li.newsDateTitle span {
color:#666;
line-height:2em;
}
#NewsList li.newsDateTitle a {
font-size:1.3em;
font-weight:bold;
color:#0083C8;
text-decoration:none;
padding-left:20px;
background:url(../images/treeicons/news-file.gif) no-repeat left center;
}
#NewsList li.newsDateTitle a:hover {
border-bottom:1px dotted #0083C8;
}
#NewsList li.newsSummary {
margin-bottom:20px;
}
#NewsList li.newsSummary span {
font-size:1.1em;
line-height:1.5em;
color:#333;
}
#NewsList li.newsSummary a.readMoreLink {
color:#0083C8;
text-decoration:none;
}
#NewsList li.newsSummary a.readMoreLink:hover {
border-bottom:1px dotted #0083C8;
}
div.newsDetails {
margin-bottom:10px;
}
div.newsDetails p {
color:#666;
margin:0;
font-size:1em;
}
div.pageComments {
background:#f0f0f0;
border:1px dotted #ccc;
padding:10px;
}
#StaffList .staffname {
clear: both;
padding-left: 60px;
height: 1.2em;
}
#StaffList .staffphoto {
float: left;
margin-left: 3px;
margin-top: -1.2em;
}
#StaffList .staffphoto img {
border:1px solid #AAA;
}
#StaffList .staffdescription {
margin-left: 60px;
margin-bottom:30px;
}
#StaffPhoto {
float: left;
margin-right: 10px;
}
#StaffPhoto img {
border:1px solid #AAA;
}
#PageComments {
list-style:none;
background:#e9e9e9;
border:1px solid #ccc;
border-bottom:0;
padding:0;
margin:0;
}
#PageComments li {
list-style:none;
padding:5px;
margin:0;
font-size:1em;
border-bottom:1px dotted #bbb;
}
#PageComments li p span {
font-style:italic;
}
#PageComments a.deletelink {
font-weight:bold;
}
#PageNumbers {
font-weight:bold;
color:#333;
font-size:1.1em;
text-align:center;
padding:5px;
border:1px solid #ddd;
background:#e9e9e9;
}
#PageNumbers * {
padding:0 5px;
line-height:1.5em;
}
#PageNumbers a {
color:#0083C8;
text-decoration:none;
}
#PageNumbers a:hover {
text-decoration:underline;
}

View File

@ -0,0 +1,113 @@
/**
* This typography file is included in the WYSIWYG editor
*/
.typography * {
font-family:Verdana,Arial,sans-serif;
font-size:1em;
}
.typography blockquote {
margin-left:20px;
}
.typography hr {
padding:5px;
}
.typography p,
.typography ul li,
.typography ol li,
.typography a {
color:#333;
line-height:1.5em;
font-size:1.1em;
}
.typography p {
margin-bottom:20px;
}
/** CMS LIST STYLES **/
.typography ul,
.typography ol {
margin-left:10px;
margin-bottom:20px;
}
.typography ul li,
.typography ol li {
margin:4px 10px;
line-height:1.4em;
}
.typography ul li {
list-style-type:disc;
}
.typography ol li {
list-style-type:decimal;
}
/* HEADER STYLES */
.typography h1,
.typography h2,
.typography h3,
.typography h4 {
margin-bottom:14px;
color:#0083C8;
}
.typography h1,
.typography h4 {
font-weight:bold;
}
.typography h2,
.typography h3 {
font-weight:normal;
}
.typography h1 {
font-size:2.2em;
}
.typography h2 {
font-size:2.2em;
}
.typography h3 {
font-size:1.6em;
}
.typography h4 {
font-size:1.4em;
}
/* LINK STYLES */
.typography a {
color:#0083C8;
font-size:1em;
text-decoration:none;
}
.typography a:hover {
text-decoration:underline;
}
.typography table {
font-size:1.1em;
}
.typography table tr td {
padding:3px 5px;
}
/* WYSIWYG EDITOR ALIGNMENT CLASSES */
.typography .left {
text-align:left;
}
.typography .center {
text-align:center;
}
.typography .right {
text-align:right;
}
.typography img.right {
float:right;
}
.typography img.left {
float:left;
}
.typography p.MsoNormal, .typography p.MsoBodyText {
margin: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<% base_tag %>
<link rel="stylesheet" type="text/css" href="tutorial/css/layout.css" />
<link rel="stylesheet" type="text/css" href="tutorial/css/typography.css" />
<link rel="stylesheet" type="text/css" href="tutorial/css/form.css" />
</head>
<body>
<div id="Main">
<div id="Header">
<h1>&nbsp;</h1>
</div>
<div id="ContentContainer">
<div id="Content" class="typography">
$Content
$Form
</div>
</div>
<div id="Footer">
<span>Visit <a href="http://www.silverstripe.org" title="Visit www.silverstripe.org">www.silverstripe.org</a> to download the CMS</span>
</div>
</div>
$SilverStripeNavigator
</body>
</html>

5
web.config Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
</system.webServer>
</configuration>