mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #1078
This commit is contained in:
commit
6cb1570282
@ -41,6 +41,7 @@
|
|||||||
*
|
*
|
||||||
* Email:
|
* Email:
|
||||||
* - SS_SEND_ALL_EMAILS_TO: If you set this define, all emails will be redirected to this address.
|
* - 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
|
* @package framework
|
||||||
* @subpackage core
|
* @subpackage core
|
||||||
@ -105,7 +106,10 @@ if(defined('SS_DATABASE_USERNAME') && defined('SS_DATABASE_PASSWORD')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(defined('SS_SEND_ALL_EMAILS_TO')) {
|
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')) {
|
if(defined('SS_DEFAULT_ADMIN_USERNAME')) {
|
||||||
|
@ -454,7 +454,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
|
|||||||
public function redirect($url, $code=302) {
|
public function redirect($url, $code=302) {
|
||||||
if(!$this->response) $this->response = new SS_HTTPResponse();
|
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')
|
user_error("Already directed to " . $this->response->getHeader('Location')
|
||||||
. "; now trying to direct to $url", E_USER_WARNING);
|
. "; now trying to direct to $url", E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
|
@ -725,6 +725,9 @@ class Director implements TemplateGlobalProvider {
|
|||||||
$matched = false;
|
$matched = false;
|
||||||
|
|
||||||
if($patterns) {
|
if($patterns) {
|
||||||
|
// Calling from the command-line?
|
||||||
|
if(!isset($_SERVER['REQUEST_URI'])) return;
|
||||||
|
|
||||||
// protect portions of the site based on the pattern
|
// protect portions of the site based on the pattern
|
||||||
$relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
|
$relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
|
||||||
foreach($patterns as $pattern) {
|
foreach($patterns as $pattern) {
|
||||||
|
@ -220,11 +220,17 @@ class SS_HTTPResponse {
|
|||||||
<meta http-equiv=\"refresh\" content=\"1; url=$url\" />
|
<meta http-equiv=\"refresh\" content=\"1; url=$url\" />
|
||||||
<script type=\"text/javascript\">setTimeout('window.location.href = \"$url\"', 50);</script>";
|
<script type=\"text/javascript\">setTimeout('window.location.href = \"$url\"', 50);</script>";
|
||||||
} else {
|
} else {
|
||||||
if(!headers_sent()) {
|
$line = $file = null;
|
||||||
|
if(!headers_sent($file, $line)) {
|
||||||
header($_SERVER['SERVER_PROTOCOL'] . " $this->statusCode " . $this->getStatusDescription());
|
header($_SERVER['SERVER_PROTOCOL'] . " $this->statusCode " . $this->getStatusDescription());
|
||||||
foreach($this->headers as $header => $value) {
|
foreach($this->headers as $header => $value) {
|
||||||
header("$header: $value", true, $this->statusCode);
|
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
|
// Only show error pages or generic "friendly" errors if the status code signifies
|
||||||
|
@ -415,7 +415,7 @@ class Session {
|
|||||||
protected function recursivelyApply($data, &$dest) {
|
protected function recursivelyApply($data, &$dest) {
|
||||||
foreach($data as $k => $v) {
|
foreach($data as $k => $v) {
|
||||||
if(is_array($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]);
|
$this->recursivelyApply($v, $dest[$k]);
|
||||||
} else {
|
} else {
|
||||||
$dest[$k] = $v;
|
$dest[$k] = $v;
|
||||||
|
@ -213,6 +213,7 @@ class Debug {
|
|||||||
|
|
||||||
public static function noticeHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
public static function noticeHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
||||||
if(error_reporting() == 0) return;
|
if(error_reporting() == 0) return;
|
||||||
|
ini_set('display_errors', 0);
|
||||||
|
|
||||||
// Send out the error details to the logger for writing
|
// Send out the error details to the logger for writing
|
||||||
SS_Log::log(
|
SS_Log::log(
|
||||||
@ -227,7 +228,9 @@ class Debug {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if(Director::isDev()) {
|
if(Director::isDev()) {
|
||||||
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Notice");
|
return self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Notice");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,8 +245,10 @@ class Debug {
|
|||||||
*/
|
*/
|
||||||
public static function warningHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
public static function warningHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
||||||
if(error_reporting() == 0) return;
|
if(error_reporting() == 0) return;
|
||||||
|
ini_set('display_errors', 0);
|
||||||
|
|
||||||
if(self::$send_warnings_to) {
|
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
|
// Send out the error details to the logger for writing
|
||||||
@ -263,7 +268,9 @@ class Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Director::isDev()) {
|
if(Director::isDev()) {
|
||||||
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Warning");
|
return self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Warning");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +286,8 @@ class Debug {
|
|||||||
* @param unknown_type $errcontext
|
* @param unknown_type $errcontext
|
||||||
*/
|
*/
|
||||||
public static function fatalHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
public static function fatalHandler($errno, $errstr, $errfile, $errline, $errcontext) {
|
||||||
|
ini_set('display_errors', 0);
|
||||||
|
|
||||||
if(self::$send_errors_to) {
|
if(self::$send_errors_to) {
|
||||||
self::emailError(self::$send_errors_to, $errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
self::emailError(self::$send_errors_to, $errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
||||||
}
|
}
|
||||||
@ -300,11 +309,10 @@ class Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Director::isDev() || Director::is_cli()) {
|
if(Director::isDev() || Director::is_cli()) {
|
||||||
self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
return self::showError($errno, $errstr, $errfile, $errline, $errcontext, "Error");
|
||||||
} else {
|
} else {
|
||||||
self::friendlyError();
|
return self::friendlyError();
|
||||||
}
|
}
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -363,6 +371,7 @@ class Debug {
|
|||||||
$renderer->writeFooter();
|
$renderer->writeFooter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -652,7 +661,7 @@ class Debug {
|
|||||||
$_SESSION['Security']['Message']['type'] = 'warning';
|
$_SESSION['Security']['Message']['type'] = 'warning';
|
||||||
$_SESSION['BackURL'] = $_SERVER['REQUEST_URI'];
|
$_SESSION['BackURL'] = $_SERVER['REQUEST_URI'];
|
||||||
header($_SERVER['SERVER_PROTOCOL'] . " 302 Found");
|
header($_SERVER['SERVER_PROTOCOL'] . " 302 Found");
|
||||||
header("Location: " . Director::baseURL() . "Security/login");
|
header("Location: " . Director::baseURL() . Security::login_url());
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -679,7 +688,7 @@ function exceptionHandler($exception) {
|
|||||||
$file = $exception->getFile();
|
$file = $exception->getFile();
|
||||||
$line = $exception->getLine();
|
$line = $exception->getLine();
|
||||||
$context = $exception->getTrace();
|
$context = $exception->getTrace();
|
||||||
Debug::fatalHandler($errno, $message, $file, $line, $context);
|
return Debug::fatalHandler($errno, $message, $file, $line, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -698,21 +707,18 @@ function errorHandler($errno, $errstr, $errfile, $errline) {
|
|||||||
case E_ERROR:
|
case E_ERROR:
|
||||||
case E_CORE_ERROR:
|
case E_CORE_ERROR:
|
||||||
case E_USER_ERROR:
|
case E_USER_ERROR:
|
||||||
Debug::fatalHandler($errno, $errstr, $errfile, $errline, debug_backtrace());
|
return Debug::fatalHandler($errno, $errstr, $errfile, $errline, debug_backtrace());
|
||||||
break;
|
|
||||||
|
|
||||||
case E_WARNING:
|
case E_WARNING:
|
||||||
case E_CORE_WARNING:
|
case E_CORE_WARNING:
|
||||||
case E_USER_WARNING:
|
case E_USER_WARNING:
|
||||||
Debug::warningHandler($errno, $errstr, $errfile, $errline, debug_backtrace());
|
return Debug::warningHandler($errno, $errstr, $errfile, $errline, debug_backtrace());
|
||||||
break;
|
|
||||||
|
|
||||||
case E_NOTICE:
|
case E_NOTICE:
|
||||||
case E_USER_NOTICE:
|
case E_USER_NOTICE:
|
||||||
case E_DEPRECATED:
|
case E_DEPRECATED:
|
||||||
case E_USER_DEPRECATED:
|
case E_USER_DEPRECATED:
|
||||||
case E_STRICT:
|
case E_STRICT:
|
||||||
Debug::noticeHandler($errno, $errstr, $errfile, $errline, debug_backtrace());
|
return Debug::noticeHandler($errno, $errstr, $errfile, $errline, debug_backtrace());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,8 +205,16 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
|
|||||||
|
|
||||||
$className = get_class($this);
|
$className = get_class($this);
|
||||||
$fixtureFile = eval("return {$className}::\$fixture_file;");
|
$fixtureFile = eval("return {$className}::\$fixture_file;");
|
||||||
|
|
||||||
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
|
$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
|
// Todo: this could be a special test model
|
||||||
$this->model = DataModel::inst();
|
$this->model = DataModel::inst();
|
||||||
|
|
||||||
@ -259,12 +267,6 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
|
|||||||
$this->logInWithPermission("ADMIN");
|
$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
|
// Preserve memory settings
|
||||||
$this->originalMemoryLimit = ini_get('memory_limit');
|
$this->originalMemoryLimit = ini_get('memory_limit');
|
||||||
|
|
||||||
|
@ -96,8 +96,12 @@ class TestSession {
|
|||||||
$form->setField(new SimpleByName($k), $v);
|
$form->setField(new SimpleByName($k), $v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($button) $submission = $form->submitButton(new SimpleByName($button));
|
if($button) {
|
||||||
else $submission = $form->submit();
|
$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());
|
$url = Director::makeRelative($form->getAction()->asString());
|
||||||
|
|
||||||
@ -137,6 +141,15 @@ class TestSession {
|
|||||||
return $this->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
|
* Get the most recent response's content
|
||||||
*/
|
*/
|
||||||
|
@ -125,16 +125,54 @@ class Email extends ViewableData {
|
|||||||
static $admin_email_address = '';
|
static $admin_email_address = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Send every email generated by the Email class to the given address.
|
||||||
|
*
|
||||||
|
* It will also add " [addressed to (email), cc to (email), bcc to (email)]" to the end of the subject line
|
||||||
|
*
|
||||||
|
* To set this, set Email.send_all_emails_to in your yml config file.
|
||||||
|
* It can also be set in _ss_environment.php with SS_SEND_ALL_EMAILS_TO.
|
||||||
|
*
|
||||||
* @param string $send_all_emails_to Email-Address
|
* @param string $send_all_emails_to Email-Address
|
||||||
*/
|
*/
|
||||||
protected static $send_all_emails_to = null;
|
protected static $send_all_emails_to = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Send every email generated by the Email class *from* the given address.
|
||||||
|
* It will also add " [, from to (email)]" to the end of the subject line
|
||||||
|
*
|
||||||
|
* To set this, set Email.send_all_emails_from in your yml config file.
|
||||||
|
* It can also be set in _ss_environment.php with SS_SEND_ALL_EMAILS_FROM.
|
||||||
|
*
|
||||||
|
* @param string $send_all_emails_from Email-Address
|
||||||
|
*/
|
||||||
|
protected static $send_all_emails_from = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BCC every email generated by the Email class to the given address.
|
||||||
|
* It won't affect the original delivery in the same way that send_all_emails_to does. It just adds a BCC header
|
||||||
|
* with the given email address. Note that you can only call this once - subsequent calls will overwrite the
|
||||||
|
* configuration variable.
|
||||||
|
*
|
||||||
|
* This can be used when you have a system that relies heavily on email and you want someone to be checking all
|
||||||
|
* correspondence.
|
||||||
|
*
|
||||||
|
* To set this, set Email.bcc_all_emails_to in your yml config file.
|
||||||
|
*
|
||||||
* @param string $bcc_all_emails_to Email-Address
|
* @param string $bcc_all_emails_to Email-Address
|
||||||
*/
|
*/
|
||||||
protected static $bcc_all_emails_to = null;
|
protected static $bcc_all_emails_to = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* CC every email generated by the Email class to the given address.
|
||||||
|
* It won't affect the original delivery in the same way that send_all_emails_to does. It just adds a CC header
|
||||||
|
* with the given email address. Note that you can only call this once - subsequent calls will overwrite the
|
||||||
|
* configuration variable.
|
||||||
|
*
|
||||||
|
* This can be used when you have a system that relies heavily on email and you want someone to be checking all
|
||||||
|
* correspondence.
|
||||||
|
*
|
||||||
|
* To set this, set Email.cc_all_emails_to in your yml config file.
|
||||||
|
*
|
||||||
* @param string $cc_all_emails_to Email-Address
|
* @param string $cc_all_emails_to Email-Address
|
||||||
*/
|
*/
|
||||||
protected static $cc_all_emails_to = null;
|
protected static $cc_all_emails_to = null;
|
||||||
@ -399,37 +437,45 @@ class Email extends ViewableData {
|
|||||||
if(project()) $headers['X-SilverStripeSite'] = project();
|
if(project()) $headers['X-SilverStripeSite'] = project();
|
||||||
|
|
||||||
$to = $this->to;
|
$to = $this->to;
|
||||||
|
$from = $this->from;
|
||||||
$subject = $this->subject;
|
$subject = $this->subject;
|
||||||
if(self::$send_all_emails_to) {
|
if($sendAllTo = $this->config()->send_all_emails_to) {
|
||||||
$subject .= " [addressed to $to";
|
$subject .= " [addressed to $to";
|
||||||
$to = self::$send_all_emails_to;
|
$to = $sendAllTo;
|
||||||
if($this->cc) $subject .= ", cc to $this->cc";
|
if($this->cc) $subject .= ", cc to $this->cc";
|
||||||
if($this->bcc) $subject .= ", bcc to $this->bcc";
|
if($this->bcc) $subject .= ", bcc to $this->bcc";
|
||||||
$subject .= ']';
|
$subject .= ']';
|
||||||
|
unset($headers['Cc']);
|
||||||
|
unset($headers['Bcc']);
|
||||||
} else {
|
} else {
|
||||||
if($this->cc) $headers['Cc'] = $this->cc;
|
if($this->cc) $headers['Cc'] = $this->cc;
|
||||||
if($this->bcc) $headers['Bcc'] = $this->bcc;
|
if($this->bcc) $headers['Bcc'] = $this->bcc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self::$cc_all_emails_to) {
|
if($ccAllTo = $this->config()->cc_all_emails_to) {
|
||||||
if(!empty($headers['Cc']) && trim($headers['Cc'])) {
|
if(!empty($headers['Cc']) && trim($headers['Cc'])) {
|
||||||
$headers['Cc'] .= ', ' . self::$cc_all_emails_to;
|
$headers['Cc'] .= ', ' . $ccAllTo;
|
||||||
} else {
|
} else {
|
||||||
$headers['Cc'] = self::$cc_all_emails_to;
|
$headers['Cc'] = $ccAllTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self::$bcc_all_emails_to) {
|
if($bccAllTo = $this->config()->bcc_all_emails_to) {
|
||||||
if(!empty($headers['Bcc']) && trim($headers['Bcc'])) {
|
if(!empty($headers['Bcc']) && trim($headers['Bcc'])) {
|
||||||
$headers['Bcc'] .= ', ' . self::$bcc_all_emails_to;
|
$headers['Bcc'] .= ', ' . $bccAllTo;
|
||||||
} else {
|
} else {
|
||||||
$headers['Bcc'] = self::$bcc_all_emails_to;
|
$headers['Bcc'] = $bccAllTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($sendAllfrom = $this->config()->send_all_emails_from) {
|
||||||
|
if($from) $subject .= " [from $from]";
|
||||||
|
$from = $sendAllfrom;
|
||||||
|
}
|
||||||
|
|
||||||
Requirements::restore();
|
Requirements::restore();
|
||||||
|
|
||||||
return self::mailer()->sendPlain($to, $this->from, $subject, $this->body, $this->attachments, $headers);
|
return self::mailer()->sendPlain($to, $from, $subject, $this->body, $this->attachments, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -459,40 +505,49 @@ class Email extends ViewableData {
|
|||||||
|
|
||||||
if(project()) $headers['X-SilverStripeSite'] = project();
|
if(project()) $headers['X-SilverStripeSite'] = project();
|
||||||
|
|
||||||
|
|
||||||
$to = $this->to;
|
$to = $this->to;
|
||||||
|
$from = $this->from;
|
||||||
$subject = $this->subject;
|
$subject = $this->subject;
|
||||||
if(self::$send_all_emails_to) {
|
if($sendAllTo = $this->config()->send_all_emails_to) {
|
||||||
$subject .= " [addressed to $to";
|
$subject .= " [addressed to $to";
|
||||||
$to = self::$send_all_emails_to;
|
$to = $sendAllTo;
|
||||||
if($this->cc) $subject .= ", cc to $this->cc";
|
if($this->cc) $subject .= ", cc to $this->cc";
|
||||||
if($this->bcc) $subject .= ", bcc to $this->bcc";
|
if($this->bcc) $subject .= ", bcc to $this->bcc";
|
||||||
$subject .= ']';
|
$subject .= ']';
|
||||||
unset($headers['Cc']);
|
unset($headers['Cc']);
|
||||||
unset($headers['Bcc']);
|
unset($headers['Bcc']);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if($this->cc) $headers['Cc'] = $this->cc;
|
if($this->cc) $headers['Cc'] = $this->cc;
|
||||||
if($this->bcc) $headers['Bcc'] = $this->bcc;
|
if($this->bcc) $headers['Bcc'] = $this->bcc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self::$cc_all_emails_to) {
|
|
||||||
|
if($ccAllTo = $this->config()->cc_all_emails_to) {
|
||||||
if(!empty($headers['Cc']) && trim($headers['Cc'])) {
|
if(!empty($headers['Cc']) && trim($headers['Cc'])) {
|
||||||
$headers['Cc'] .= ', ' . self::$cc_all_emails_to;
|
$headers['Cc'] .= ', ' . $ccAllTo;
|
||||||
} else {
|
} else {
|
||||||
$headers['Cc'] = self::$cc_all_emails_to;
|
$headers['Cc'] = $ccAllTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self::$bcc_all_emails_to) {
|
if($bccAllTo = $this->config()->bcc_all_emails_to) {
|
||||||
if(!empty($headers['Bcc']) && trim($headers['Bcc'])) {
|
if(!empty($headers['Bcc']) && trim($headers['Bcc'])) {
|
||||||
$headers['Bcc'] .= ', ' . self::$bcc_all_emails_to;
|
$headers['Bcc'] .= ', ' . $bccAllTo;
|
||||||
} else {
|
} else {
|
||||||
$headers['Bcc'] = self::$bcc_all_emails_to;
|
$headers['Bcc'] = $bccAllTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($sendAllfrom = $this->config()->send_all_emails_from) {
|
||||||
|
if($from) $subject .= " [from $from]";
|
||||||
|
$from = $sendAllfrom;
|
||||||
|
}
|
||||||
|
|
||||||
Requirements::restore();
|
Requirements::restore();
|
||||||
|
|
||||||
return self::mailer()->sendHTML($to, $this->from, $subject, $this->body, $this->attachments, $headers,
|
return self::mailer()->sendHTML($to, $from, $subject, $this->body, $this->attachments, $headers,
|
||||||
$this->plaintext_body);
|
$this->plaintext_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ function encodeMultipart($parts, $contentType, $headers = false) {
|
|||||||
*/
|
*/
|
||||||
function wrapImagesInline($htmlContent) {
|
function wrapImagesInline($htmlContent) {
|
||||||
global $_INLINED_IMAGES;
|
global $_INLINED_IMAGES;
|
||||||
$_INLINED_IMAGES = null;
|
$_INLINED_IMAGES = array();
|
||||||
|
|
||||||
$replacedContent = imageRewriter($htmlContent, 'wrapImagesInline_rewriter($URL)');
|
$replacedContent = imageRewriter($htmlContent, 'wrapImagesInline_rewriter($URL)');
|
||||||
|
|
||||||
@ -303,8 +303,8 @@ function wrapImagesInline($htmlContent) {
|
|||||||
|
|
||||||
// Make all the image parts
|
// Make all the image parts
|
||||||
global $_INLINED_IMAGES;
|
global $_INLINED_IMAGES;
|
||||||
foreach($_INLINED_IMAGES as $url => $cid) {
|
if($_INLINED_IMAGES) foreach($_INLINED_IMAGES as $url => $cid) {
|
||||||
$multiparts[] = encodeFileForEmail($url, false, "inline", "Content-ID: <$cid>\n");
|
$multiparts[] = encodeFileForEmail(BASE_PATH . '/' . $url, false, "inline", "Content-ID: <$cid>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge together in a multipart
|
// Merge together in a multipart
|
||||||
@ -312,10 +312,10 @@ function wrapImagesInline($htmlContent) {
|
|||||||
return processHeaders($headers, $body);
|
return processHeaders($headers, $body);
|
||||||
}
|
}
|
||||||
function wrapImagesInline_rewriter($url) {
|
function wrapImagesInline_rewriter($url) {
|
||||||
$url = relativiseURL($url);
|
$url = Director::makeRelative($url);
|
||||||
|
|
||||||
global $_INLINED_IMAGES;
|
global $_INLINED_IMAGES;
|
||||||
if(!$_INLINED_IMAGES[$url]) {
|
if(!isset($_INLINED_IMAGES[$url])) {
|
||||||
$identifier = "automatedmessage." . rand(1000,1000000000) . "@silverstripe.com";
|
$identifier = "automatedmessage." . rand(1000,1000000000) . "@silverstripe.com";
|
||||||
$_INLINED_IMAGES[$url] = $identifier;
|
$_INLINED_IMAGES[$url] = $identifier;
|
||||||
}
|
}
|
||||||
@ -384,6 +384,7 @@ function encodeFileForEmail($file, $destFileName = false, $disposition = NULL, $
|
|||||||
$file = array('filename' => $file);
|
$file = array('filename' => $file);
|
||||||
$fh = fopen($file['filename'], "rb");
|
$fh = fopen($file['filename'], "rb");
|
||||||
if ($fh) {
|
if ($fh) {
|
||||||
|
$file['contents'] = "";
|
||||||
while(!feof($fh)) $file['contents'] .= fread($fh, 10000);
|
while(!feof($fh)) $file['contents'] .= fread($fh, 10000);
|
||||||
fclose($fh);
|
fclose($fh);
|
||||||
}
|
}
|
||||||
@ -393,12 +394,12 @@ function encodeFileForEmail($file, $destFileName = false, $disposition = NULL, $
|
|||||||
if(!$destFileName) $base = basename($file['filename']);
|
if(!$destFileName) $base = basename($file['filename']);
|
||||||
else $base = $destFileName;
|
else $base = $destFileName;
|
||||||
|
|
||||||
$mimeType = $file['mimetype'] ? $file['mimetype'] : HTTP::get_mime_type($file['filename']);
|
$mimeType = !empty($file['mimetype']) ? $file['mimetype'] : HTTP::get_mime_type($file['filename']);
|
||||||
if(!$mimeType) $mimeType = "application/unknown";
|
if(!$mimeType) $mimeType = "application/unknown";
|
||||||
if (empty($disposition)) $disposition = isset($file['contentLocation']) ? 'inline' : 'attachment';
|
if (empty($disposition)) $disposition = isset($file['contentLocation']) ? 'inline' : 'attachment';
|
||||||
|
|
||||||
// Encode for emailing
|
// Encode for emailing
|
||||||
if (substr($file['mimetype'], 0, 4) != 'text') {
|
if (substr($mimeType, 0, 4) != 'text') {
|
||||||
$encoding = "base64";
|
$encoding = "base64";
|
||||||
$file['contents'] = chunk_split(base64_encode($file['contents']));
|
$file['contents'] = chunk_split(base64_encode($file['contents']));
|
||||||
} else {
|
} else {
|
||||||
|
@ -250,7 +250,9 @@ class Form extends RequestHandler {
|
|||||||
// Protection against CSRF attacks
|
// Protection against CSRF attacks
|
||||||
$token = $this->getSecurityToken();
|
$token = $this->getSecurityToken();
|
||||||
if(!$token->checkRequest($request)) {
|
if(!$token->checkRequest($request)) {
|
||||||
$this->httpError(400, "Sorry, your session has timed out.");
|
$this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE",
|
||||||
|
"There seems to have been a technical problem. Please click the back button,"
|
||||||
|
. " refresh your browser, and try again."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the action button clicked
|
// Determine the action button clicked
|
||||||
|
@ -35,7 +35,7 @@ class RequiredFields extends Validator {
|
|||||||
* Clears all the validation from this object.
|
* Clears all the validation from this object.
|
||||||
*/
|
*/
|
||||||
public function removeValidation(){
|
public function removeValidation(){
|
||||||
$this->required = null;
|
$this->required = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,6 +55,9 @@ class ArrayList extends ViewableData implements SS_List, SS_Filterable, SS_Sorta
|
|||||||
* @return ArrayIterator
|
* @return ArrayIterator
|
||||||
*/
|
*/
|
||||||
public function getIterator() {
|
public function getIterator() {
|
||||||
|
foreach($this->items as $i => $item) {
|
||||||
|
if(is_array($item)) $this->items[$i] = new ArrayData($item);
|
||||||
|
}
|
||||||
return new ArrayIterator($this->items);
|
return new ArrayIterator($this->items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ class Date extends DBField {
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function InPast() {
|
public function InPast() {
|
||||||
return strtotime($this->value) < time();
|
return strtotime($this->value) < SS_Datetime::now()->Format('U');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -310,7 +310,7 @@ class Date extends DBField {
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function InFuture() {
|
public function InFuture() {
|
||||||
return strtotime($this->value) > time();
|
return strtotime($this->value) > SS_Datetime::now()->Format('U');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -318,7 +318,7 @@ class Date extends DBField {
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function IsToday() {
|
public function IsToday() {
|
||||||
return (date('Y-m-d', strtotime($this->value)) == date('Y-m-d', time()));
|
return (date('Y-m-d', strtotime($this->value)) == SS_Datetime::now()->Format('Y-m-d'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,8 +136,21 @@ class HTMLText extends Text {
|
|||||||
return ShortcodeParser::get_active()->parse($this->value);
|
return ShortcodeParser::get_active()->parse($this->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the field has meaningful content.
|
||||||
|
* Excludes null content like <h1></h1>, <p></p> ,etc
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
public function exists() {
|
public function exists() {
|
||||||
return parent::exists() && $this->value != '<p></p>';
|
// If it's blank, it's blank
|
||||||
|
if(!parent::exists()) return false;
|
||||||
|
// If it's got a content tag
|
||||||
|
if(preg_match('/<(img|embed|object|iframe)[^>]*>/i', $this->value)) return true;
|
||||||
|
// If it's just one or two tags on its own (and not the above) it's empty. This might be <p></p> or <h1></h1> or whatever.
|
||||||
|
if(preg_match('/^[\\s]*(<[^>]+>[\\s]*){1,2}$/', $this->value)) return false;
|
||||||
|
// Otherwise its content is genuine content
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scaffoldFormField($title = null, $params = null) {
|
public function scaffoldFormField($title = null, $params = null) {
|
||||||
|
@ -242,7 +242,10 @@ class Security extends Controller {
|
|||||||
// Audit logging hook
|
// Audit logging hook
|
||||||
$controller->extend('permissionDenied', $member);
|
$controller->extend('permissionDenied', $member);
|
||||||
|
|
||||||
$controller->redirect("Security/login?BackURL=" . urlencode($_SERVER['REQUEST_URI']));
|
$controller->redirect(
|
||||||
|
Config::inst()->get('Security', 'login_url')
|
||||||
|
. "?BackURL=" . urlencode($_SERVER['REQUEST_URI'])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -927,8 +930,25 @@ class Security extends Controller {
|
|||||||
public static function set_ignore_disallowed_actions($flag) {
|
public static function set_ignore_disallowed_actions($flag) {
|
||||||
self::$ignore_disallowed_actions = $flag;
|
self::$ignore_disallowed_actions = $flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function ignore_disallowed_actions() {
|
public static function ignore_disallowed_actions() {
|
||||||
return self::$ignore_disallowed_actions;
|
return self::$ignore_disallowed_actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static $login_url = "Security/login";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a custom log-in URL if you have built your own log-in page.
|
||||||
|
*/
|
||||||
|
public static function set_login_url($loginUrl) {
|
||||||
|
self::$login_url = $loginUrl;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the URL of the log-in page.
|
||||||
|
* Defaults to Security/login but can be re-set with {@link set_login_url()}
|
||||||
|
*/
|
||||||
|
public static function login_url() {
|
||||||
|
return self::$login_url;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
<form $FormAttributes>
|
<form $FormAttributes>
|
||||||
|
<% if Message %>
|
||||||
|
<p id="{$FormName}_error" class="message $MessageType">$Message</p>
|
||||||
|
<% else %>
|
||||||
|
<p id="{$FormName}_error" class="message $MessageType" style="display: none"></p>
|
||||||
|
<% end_if %>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<% loop Fields %>
|
<% loop Fields %>
|
||||||
$FieldHolder
|
$FieldHolder
|
||||||
|
@ -252,7 +252,7 @@ class DirectorTest extends SapphireTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testForceSSLOnSubPagesPattern() {
|
public function testForceSSLOnSubPagesPattern() {
|
||||||
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'Security/login';
|
$_SERVER['REQUEST_URI'] = Director::baseURL() . Config::inst()->get('Security', 'login_url');
|
||||||
$output = Director::forceSSL(array('/^Security/'));
|
$output = Director::forceSSL(array('/^Security/'));
|
||||||
$this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
$this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||||
}
|
}
|
||||||
|
@ -139,4 +139,38 @@ class HTMLTextTest extends SapphireTest {
|
|||||||
$data = DBField::create_field('HTMLText', '"this is a test"');
|
$data = DBField::create_field('HTMLText', '"this is a test"');
|
||||||
$this->assertEquals($data->ATT(), '"this is a test"');
|
$this->assertEquals($data->ATT(), '"this is a test"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testExists() {
|
||||||
|
$h = new HTMLText;
|
||||||
|
$h->setValue("");
|
||||||
|
$this->assertFalse($h->exists());
|
||||||
|
$h->setValue("<p></p>");
|
||||||
|
$this->assertFalse($h->exists());
|
||||||
|
$h->setValue("<p> </p>");
|
||||||
|
$this->assertFalse($h->exists());
|
||||||
|
$h->setValue("<h2/>");
|
||||||
|
$this->assertFalse($h->exists());
|
||||||
|
$h->setValue("<h2></h2>");
|
||||||
|
$this->assertFalse($h->exists());
|
||||||
|
|
||||||
|
$h->setValue("something");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
$h->setValue("<img src=\"dummy.png\">");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
$h->setValue("<img src=\"dummy.png\"><img src=\"dummy.png\">");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
$h->setValue("<p><img src=\"dummy.png\"></p>");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
|
||||||
|
$h->setValue("<iframe src=\"http://www.google.com\"></iframe>");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
$h->setValue("<embed src=\"test.swf\">");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
$h->setValue("<object width=\"400\" height=\"400\" data=\"test.swf\"></object>");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
|
||||||
|
|
||||||
|
$h->setValue("<p>test</p>");
|
||||||
|
$this->assertTrue($h->exists());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,10 @@ class SecurityTest extends FunctionalTest {
|
|||||||
|
|
||||||
$response = $this->get('SecurityTest_SecuredController');
|
$response = $this->get('SecurityTest_SecuredController');
|
||||||
$this->assertEquals(302, $response->getStatusCode());
|
$this->assertEquals(302, $response->getStatusCode());
|
||||||
$this->assertContains('Security/login', $response->getHeader('Location'));
|
$this->assertContains(
|
||||||
|
Config::inst()->get('Security', 'login_url'),
|
||||||
|
$response->getHeader('Location')
|
||||||
|
);
|
||||||
|
|
||||||
$this->logInWithPermission('ADMIN');
|
$this->logInWithPermission('ADMIN');
|
||||||
$response = $this->get('SecurityTest_SecuredController');
|
$response = $this->get('SecurityTest_SecuredController');
|
||||||
@ -74,7 +77,7 @@ class SecurityTest extends FunctionalTest {
|
|||||||
$this->session()->inst_set('loggedInAs', $member->ID);
|
$this->session()->inst_set('loggedInAs', $member->ID);
|
||||||
|
|
||||||
/* View the Security/login page */
|
/* View the Security/login page */
|
||||||
$response = $this->get('Security/login');
|
$response = $this->get(Config::inst()->get('Security', 'login_url'));
|
||||||
|
|
||||||
$items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.action');
|
$items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.action');
|
||||||
|
|
||||||
@ -108,7 +111,7 @@ class SecurityTest extends FunctionalTest {
|
|||||||
$this->autoFollowRedirection = true;
|
$this->autoFollowRedirection = true;
|
||||||
|
|
||||||
/* Attempt to get into the admin section */
|
/* Attempt to get into the admin section */
|
||||||
$response = $this->get('Security/login/');
|
$response = $this->get(Config::inst()->get('Security', 'login_url'));
|
||||||
|
|
||||||
$items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.text');
|
$items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.text');
|
||||||
|
|
||||||
@ -396,7 +399,7 @@ class SecurityTest extends FunctionalTest {
|
|||||||
public function doTestLoginForm($email, $password, $backURL = 'test/link') {
|
public function doTestLoginForm($email, $password, $backURL = 'test/link') {
|
||||||
$this->get('Security/logout');
|
$this->get('Security/logout');
|
||||||
$this->session()->inst_set('BackURL', $backURL);
|
$this->session()->inst_set('BackURL', $backURL);
|
||||||
$this->get('Security/login');
|
$this->get(Config::inst()->get('Security', 'login_url'));
|
||||||
|
|
||||||
return $this->submitForm(
|
return $this->submitForm(
|
||||||
"MemberLoginForm_LoginForm",
|
"MemberLoginForm_LoginForm",
|
||||||
|
Loading…
Reference in New Issue
Block a user