Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/3.0' into 3.1
Browse files Browse the repository at this point in the history
Conflicts:
	email/Mailer.php
  • Loading branch information
chillu committed Jan 30, 2013
2 parents eb7fed9 + c9f728f commit 634c91c
Show file tree
Hide file tree
Showing 35 changed files with 358 additions and 85 deletions.
6 changes: 5 additions & 1 deletion conf/ConfigureFromEnv.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
*
* Email:
* - SS_SEND_ALL_EMAILS_TO: If you set this define, all emails will be redirected to this address.
* - SS_SEND_ALL_EMAILS_FROM: If you set this define, all emails will be send from this address.
*
* @package framework
* @subpackage core
Expand Down Expand Up @@ -105,7 +106,10 @@
}

if(defined('SS_SEND_ALL_EMAILS_TO')) {
Email::send_all_emails_to(SS_SEND_ALL_EMAILS_TO);
Config::inst()->update("Email","send_all_emails_to", SS_SEND_ALL_EMAILS_TO);
}
if(defined('SS_SEND_ALL_EMAILS_FROM')) {
Config::inst()->update("Email","send_all_emails_from", SS_SEND_ALL_EMAILS_FROM);
}

if(defined('SS_DEFAULT_ADMIN_USERNAME')) {
Expand Down
2 changes: 1 addition & 1 deletion control/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ public function popCurrent() {
public function redirect($url, $code=302) {
if(!$this->response) $this->response = new SS_HTTPResponse();

if($this->response->getHeader('Location')) {
if($this->response->getHeader('Location') && $this->response->getHeader('Location') != $url) {
user_error("Already directed to " . $this->response->getHeader('Location')
. "; now trying to direct to $url", E_USER_WARNING);
return;
Expand Down
3 changes: 3 additions & 0 deletions control/Director.php
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,9 @@ public static function forceSSL($patterns = null) {
$matched = false;

if($patterns) {
// Calling from the command-line?
if(!isset($_SERVER['REQUEST_URI'])) return;

// protect portions of the site based on the pattern
$relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
foreach($patterns as $pattern) {
Expand Down
8 changes: 7 additions & 1 deletion control/HTTPResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,17 @@ public function output() {
<meta http-equiv=\"refresh\" content=\"1; url=$url\" />
<script type=\"text/javascript\">setTimeout('window.location.href = \"$url\"', 50);</script>";
} else {
if(!headers_sent()) {
$line = $file = null;
if(!headers_sent($file, $line)) {
header($_SERVER['SERVER_PROTOCOL'] . " $this->statusCode " . $this->getStatusDescription());
foreach($this->headers as $header => $value) {
header("$header: $value", true, $this->statusCode);
}
} else {
// It's critical that these status codes are sent; we need to report a failure if not.
if($this->statusCode >= 300) {
user_error("Couldn't set response type to $this->statusCode because of output on line $line of $file", E_USER_WARNING);
}
}

// Only show error pages or generic "friendly" errors if the status code signifies
Expand Down
2 changes: 2 additions & 0 deletions control/RequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ public function handleRequest(SS_HTTPRequest $request, DataModel $model) {
$result = $this->$action($request);
} catch(SS_HTTPResponse_Exception $responseException) {
$result = $responseException->getResponse();
} catch(PermissionFailureException $e) {
$result = Security::permissionFailure(null, $e->getMessage());
}
} else {
return $this->httpError(403, "Action '$action' isn't allowed on class " . get_class($this));
Expand Down
2 changes: 1 addition & 1 deletion control/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ public function inst_save() {
protected function recursivelyApply($data, &$dest) {
foreach($data as $k => $v) {
if(is_array($v)) {
if(!isset($dest[$k])) $dest[$k] = array();
if(!isset($dest[$k]) || !is_array($dest[$k])) $dest[$k] = array();
$this->recursivelyApply($v, $dest[$k]);
} else {
$dest[$k] = $v;
Expand Down
36 changes: 21 additions & 15 deletions dev/Debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ public static function loadErrorHandlers() {

public static function noticeHandler($errno, $errstr, $errfile, $errline, $errcontext) {
if(error_reporting() == 0) return;
ini_set('display_errors', 0);

// Send out the error details to the logger for writing
SS_Log::log(
Expand All @@ -237,7 +238,9 @@ public static function noticeHandler($errno, $errstr, $errfile, $errline, $errco
);

if(Director::isDev()) {
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Notice");
return self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Notice");
} else {
return false;
}
}

Expand All @@ -252,8 +255,10 @@ public static function noticeHandler($errno, $errstr, $errfile, $errline, $errco
*/
public static function warningHandler($errno, $errstr, $errfile, $errline, $errcontext) {
if(error_reporting() == 0) return;
ini_set('display_errors', 0);

if(self::$send_warnings_to) {
self::emailError(self::$send_warnings_to, $errno, $errstr, $errfile, $errline, $errcontext, "Warning");
return self::emailError(self::$send_warnings_to, $errno, $errstr, $errfile, $errline, $errcontext, "Warning");
}

// Send out the error details to the logger for writing
Expand All @@ -273,8 +278,10 @@ public static function warningHandler($errno, $errstr, $errfile, $errline, $errc
}

if(Director::isDev()) {
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Warning");
}
return self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Warning");
} else {
return false;
}
}

/**
Expand All @@ -289,6 +296,8 @@ public static function warningHandler($errno, $errstr, $errfile, $errline, $errc
* @param unknown_type $errcontext
*/
public static function fatalHandler($errno, $errstr, $errfile, $errline, $errcontext) {
ini_set('display_errors', 0);

if(self::$send_errors_to) {
self::emailError(self::$send_errors_to, $errno, $errstr, $errfile, $errline, $errcontext, "Error");
}
Expand All @@ -310,11 +319,10 @@ public static function fatalHandler($errno, $errstr, $errfile, $errline, $errcon
}

if(Director::isDev() || Director::is_cli()) {
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Error");
return self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Error");
} else {
self::friendlyError();
return self::friendlyError();
}
exit(1);
}

/**
Expand Down Expand Up @@ -373,6 +381,7 @@ class_exists('Translatable') ? Translatable::get_current_locale() : null
$renderer->writeFooter();
}
}
return false;
}

/**
Expand Down Expand Up @@ -497,7 +506,7 @@ public static function require_developer_login() {
$_SESSION['Security']['Message']['type'] = 'warning';
$_SESSION['BackURL'] = $_SERVER['REQUEST_URI'];
header($_SERVER['SERVER_PROTOCOL'] . " 302 Found");
header("Location: " . Director::baseURL() . "Security/login");
header("Location: " . Director::baseURL() . Security::login_url());
die();
}
}
Expand All @@ -524,7 +533,7 @@ function exceptionHandler($exception) {
$file = $exception->getFile();
$line = $exception->getLine();
$context = $exception->getTrace();
Debug::fatalHandler($errno, $message, $file, $line, $context);
return Debug::fatalHandler($errno, $message, $file, $line, $context);
}

/**
Expand All @@ -543,21 +552,18 @@ function errorHandler($errno, $errstr, $errfile, $errline) {
case E_ERROR:
case E_CORE_ERROR:
case E_USER_ERROR:
Debug::fatalHandler($errno, $errstr, $errfile, $errline, null);
break;
return Debug::fatalHandler($errno, $errstr, $errfile, $errline, debug_backtrace());

case E_WARNING:
case E_CORE_WARNING:
case E_USER_WARNING:
Debug::warningHandler($errno, $errstr, $errfile, $errline, null);
break;
return Debug::warningHandler($errno, $errstr, $errfile, $errline, debug_backtrace());

case E_NOTICE:
case E_USER_NOTICE:
case E_DEPRECATED:
case E_USER_DEPRECATED:
case E_STRICT:
Debug::noticeHandler($errno, $errstr, $errfile, $errline, null);
break;
return Debug::noticeHandler($errno, $errstr, $errfile, $errline, debug_backtrace());
}
}
7 changes: 2 additions & 5 deletions dev/LogErrorEmailFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ public function format($event) {
$data .= "<p style=\"color: white; background-color: $colour; margin: 0\">"
. "[$errorType] $errstr<br />$errfile:$errline\n<br />\n<br />\n</p>\n";

// Get a backtrace, filtering out debug method calls
$data .= SS_Backtrace::backtrace(true, false, array(
'SS_LogErrorEmailFormatter->format',
'SS_LogEmailWriter->_write'
));
// Render the provided backtrace
$data .= SS_Backtrace::get_rendered_backtrace($errcontext);

// Compile extra data
$blacklist = array('message', 'timestamp', 'priority', 'priorityName');
Expand Down
14 changes: 8 additions & 6 deletions dev/SapphireTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,15 @@ public function setUp() {

$className = get_class($this);
$fixtureFile = eval("return {$className}::\$fixture_file;");

$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';

// Set up email
$this->originalMailer = Email::mailer();
$this->mailer = new TestMailer();
Email::set_mailer($this->mailer);
Config::inst()->remove('Email', 'send_all_emails_to');
Email::send_all_emails_to(null);

// Todo: this could be a special test model
$this->model = DataModel::inst();
Expand Down Expand Up @@ -259,12 +267,6 @@ public function setUp() {
$this->logInWithPermission("ADMIN");
}

// Set up email
$this->originalMailer = Email::mailer();
$this->mailer = new TestMailer();
Email::set_mailer($this->mailer);
Email::send_all_emails_to(null);

// Preserve memory settings
$this->originalMemoryLimit = ini_get('memory_limit');

Expand Down
17 changes: 15 additions & 2 deletions dev/TestSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,12 @@ public function submitForm($formID, $button = null, $data = array()) {
$form->setField(new SimpleByName($k), $v);
}

if($button) $submission = $form->submitButton(new SimpleByName($button));
else $submission = $form->submit();
if($button) {
$submission = $form->submitButton(new SimpleByName($button));
if(!$submission) throw new Exception("Can't find button '$button' to submit as part of test.");
} else {
$submission = $form->submit();
}

$url = Director::makeRelative($form->getAction()->asString());

Expand Down Expand Up @@ -137,6 +141,15 @@ public function lastResponse() {
return $this->lastResponse;
}

/**
* Return the fake HTTP_REFERER; set each time get() or post() is called.
*
* @return string
*/
public function lastUrl() {
return $this->lastUrl;
}

/**
* Get the most recent response's content
*/
Expand Down
7 changes: 7 additions & 0 deletions dev/install/install.php5
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,13 @@ HTML;
Deny from all
</Files>
# This denies access to all yml files, since developers might include sensitive
# information in them. See the docs for work-arounds to serve some yaml files
<Files *.yml>
Order allow,deny
Deny from all
</Files>
ErrorDocument 404 /assets/error-404.html
ErrorDocument 500 /assets/error-500.html
Expand Down
2 changes: 1 addition & 1 deletion docs/en/changelogs/3.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Any arrays you pass as values to `update()` will be automatically merged. To rep

Note the different options for the third parameter of `get()`:

* `Config::INHERITED` will only get the configuration set for the specific class, not any of it's parents.
* `Config::UNINHERITED` will only get the configuration set for the specific class, not any of it's parents.
* `Config::FIRST_SET` will inherit configuration from parents, but stop on the first class that actually provides a value.
* `Config::EXCLUDE_EXTRA_SOURCES` will not use additional static sources (such as those defined on extensions)

Expand Down
9 changes: 7 additions & 2 deletions docs/en/installation/nginx.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ configuration settings:
index index.php index.html index.htm;
server_name example.com;

include silverstripe3;
include htaccess;
}
Expand All @@ -29,7 +29,7 @@ Here is the include file `silverstripe3`:
location / {
try_files $uri @silverstripe;
}

location @silverstripe {
include fastcgi_params;
Expand Down Expand Up @@ -68,6 +68,11 @@ Here is the include file `htaccess`:
try_files $uri $uri/ =404;
}

# Block access to yaml files
location ~ \.yml$ {
deny all;
}

# cms & framework .htaccess rules
location ~ ^/(cms|framework|mysite)/.*\.(php|php[345]|phtml|inc)$ {
deny all;
Expand Down
16 changes: 15 additions & 1 deletion docs/en/installation/webserver.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,18 @@ name' and the default login details. Follow the questions and select the *instal

## Issues?

If the above steps don't work for any reason have a read of the [Common Problems](common-problems) section.
If the above steps don't work for any reason have a read of the [Common Problems](common-problems) section.

## Security notes

### Yaml

For the reasons explained in [security](/topics/security) Yaml files are blocked by default by the .htaccess file
provided by the SilverStripe installer module.

To allow serving yaml files from a specific directory, add code like this to an .htaccess file in that directory

<Files *.yml>
Order allow,deny
Allow from all
</Files>
2 changes: 1 addition & 1 deletion docs/en/reference/database-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ left-join for robustness; if there is no matching record in Page, we can return

SilverStripe has a powerful tool for automatically building database schemas. We've designed it so that you should never have to build them manually.

To access it, visit (site-root)/dev/build?flush=1. This script will analyze the existing schema, compare it to what's required by your data classes, and alter the schema as required.
To access it, visit http://<mysite>/dev/build?flush=1. This script will analyze the existing schema, compare it to what's required by your data classes, and alter the schema as required.

Put the ?flush=1 on the end if you've added PHP files, so that the rest of the system will find these new classes.

Expand Down
6 changes: 3 additions & 3 deletions docs/en/reference/sqlquery.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ We'll explain some ways to use *SELECT* with the full power of SQL,
but still maintain a connection to the ORM where possible.

<div class="warning" markdown="1">
Please read our ["security" topic](/topics/security) to find out
how to sanitize user input before using it in SQL queries.
Please read our ["security" topic](/topics/security) to find out
how to sanitize user input before using it in SQL queries.
</div>

## Usage
Expand Down Expand Up @@ -140,4 +140,4 @@ An alternative approach would be a custom getter in the object definition.

* [datamodel](/topics/datamodel)
* `[api:DataObject]`
* [database-structure](database-structure)
* [database-structure](database-structure)
4 changes: 2 additions & 2 deletions docs/en/reference/urlvariabletools.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Append the option and corresponding value to your URL in your browser's address

| URL Variable | | Values | | Description |
| ------------ | | ------ | | ----------- |
| isDev | | 1 | | Put the site into [development mode](/topics/debugging), enabling debugging messages to the browser on a live server. For security, you'll be asked to log in with an administrator log-in |
| isTest | | 1 | | Put the site into [test mode](/topics/debugging), enabling debugging messages to the admin email and generic errors to the browser on a live server |
| isDev | | 1 | | Put the site into [development mode](/topics/debugging), enabling debugging messages to the browser on a live server. For security, you'll be asked to log in with an administrator log-in. Will persist for the current browser session. |
| isTest | | 1 | | See above. |
| debug | | 1 | | Show a collection of debugging information about the director / controller operation |
| debug_request | | 1 | | Show all steps of the request from initial `[api:HTTPRequest]` to `[api:Controller]` to Template Rendering |

Expand Down
3 changes: 2 additions & 1 deletion docs/en/topics/datamodel.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ The SilverStripe database-schema is generated automatically by visiting the URL.
`http://<mysite>/dev/build`

<div class="notice" markdown='1'>
Note: You need to be logged in as an administrator to perform this command.
Note: You need to be logged in as an administrator to perform this command,
unless your site is in "[dev mode](/topics/debugging)", or the command is run through CLI.
</div>

## Querying Data
Expand Down
Loading

0 comments on commit 634c91c

Please sign in to comment.