mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge remote-tracking branch 'origin/3.0' into 3.1
Conflicts: control/Director.php
This commit is contained in:
commit
91f6039eed
@ -42,7 +42,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $test_servers = array();
|
private static $test_servers = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setting this explicitly specifies the protocol (http or https) used, overriding
|
* Setting this explicitly specifies the protocol (http or https) used, overriding
|
||||||
* the normal behaviour of Director::is_https introspecting it from the request
|
* the normal behaviour of Director::is_https introspecting it from the request
|
||||||
@ -51,13 +51,13 @@ class Director implements TemplateGlobalProvider {
|
|||||||
* @var string - "http" or "https" to force the protocol, or false-ish to use default introspection from request
|
* @var string - "http" or "https" to force the protocol, or false-ish to use default introspection from request
|
||||||
*/
|
*/
|
||||||
private static $alternate_protocol;
|
private static $alternate_protocol;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $alternate_base_url;
|
private static $alternate_base_url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var string
|
* @var string
|
||||||
@ -68,7 +68,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
* Add URL matching rules to the Director.
|
* Add URL matching rules to the Director.
|
||||||
*
|
*
|
||||||
* The director is responsible for turning URLs into Controller objects.
|
* The director is responsible for turning URLs into Controller objects.
|
||||||
*
|
*
|
||||||
* @deprecated 3.2 Use the "Director.rules" config setting instead
|
* @deprecated 3.2 Use the "Director.rules" config setting instead
|
||||||
* @param $priority The priority of the rules; higher values will get your rule checked first. We recommend
|
* @param $priority The priority of the rules; higher values will get your rule checked first. We recommend
|
||||||
* priority 100 for your site's rules. The built-in rules are priority 10, standard modules are
|
* priority 100 for your site's rules. The built-in rules are priority 10, standard modules are
|
||||||
@ -165,13 +165,13 @@ class Director implements TemplateGlobalProvider {
|
|||||||
DataModel::inst()
|
DataModel::inst()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$response = new SS_HTTPResponse();
|
$response = new SS_HTTPResponse();
|
||||||
$response->redirect($url);
|
$response->redirect($url);
|
||||||
$res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
|
$res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
|
||||||
|
|
||||||
if ($res !== false) {
|
if ($res !== false) {
|
||||||
$response->output();
|
$response->output();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle a controller
|
// Handle a controller
|
||||||
} else if($result) {
|
} else if($result) {
|
||||||
@ -185,7 +185,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
|
|
||||||
$res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
|
$res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
|
||||||
if ($res !== false) {
|
if ($res !== false) {
|
||||||
$response->output();
|
$response->output();
|
||||||
} else {
|
} else {
|
||||||
// @TODO Proper response here.
|
// @TODO Proper response here.
|
||||||
throw new SS_HTTPResponse_Exception("Invalid response");
|
throw new SS_HTTPResponse_Exception("Invalid response");
|
||||||
@ -279,7 +279,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
|
|
||||||
// TODO: Pass in the DataModel
|
// TODO: Pass in the DataModel
|
||||||
$result = Director::handleRequest($request, $session, $model);
|
$result = Director::handleRequest($request, $session, $model);
|
||||||
|
|
||||||
// Ensure that the result is an SS_HTTPResponse object
|
// Ensure that the result is an SS_HTTPResponse object
|
||||||
if(is_string($result)) {
|
if(is_string($result)) {
|
||||||
if(substr($result,0,9) == 'redirect:') {
|
if(substr($result,0,9) == 'redirect:') {
|
||||||
@ -309,7 +309,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
// These are needed so that calling Director::test() doesnt muck with whoever is calling it.
|
// These are needed so that calling Director::test() doesnt muck with whoever is calling it.
|
||||||
// Really, it's some inappropriate coupling and should be resolved by making less use of statics
|
// Really, it's some inappropriate coupling and should be resolved by making less use of statics
|
||||||
Versioned::reading_stage($oldStage);
|
Versioned::reading_stage($oldStage);
|
||||||
|
|
||||||
Config::unnest();
|
Config::unnest();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@ -368,7 +368,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No URL rules matched, so return a 404 error.
|
// No URL rules matched, so return a 404 error.
|
||||||
return new SS_HTTPResponse('No URL rule was matched', 404);
|
return new SS_HTTPResponse('No URL rule was matched', 404);
|
||||||
}
|
}
|
||||||
@ -459,7 +459,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
*/
|
*/
|
||||||
public static function protocol() {
|
public static function protocol() {
|
||||||
return (self::is_https()) ? 'https://' : 'http://';
|
return (self::is_https()) ? 'https://' : 'http://';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the site is running as under HTTPS.
|
* Return whether the site is running as under HTTPS.
|
||||||
@ -469,17 +469,17 @@ class Director implements TemplateGlobalProvider {
|
|||||||
public static function is_https() {
|
public static function is_https() {
|
||||||
if ($protocol = Config::inst()->get('Director', 'alternate_protocol')) {
|
if ($protocol = Config::inst()->get('Director', 'alternate_protocol')) {
|
||||||
return $protocol == 'https';
|
return $protocol == 'https';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) {
|
if(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) {
|
||||||
if(strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https') {
|
if(strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) {
|
if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(isset($_SERVER['SSL'])) {
|
else if(isset($_SERVER['SSL'])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -507,12 +507,12 @@ class Director implements TemplateGlobalProvider {
|
|||||||
$baseURL = '/';
|
$baseURL = '/';
|
||||||
} else {
|
} else {
|
||||||
$baseURL = $base . '/';
|
$baseURL = $base . '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(defined('BASE_SCRIPT_URL')) {
|
if(defined('BASE_SCRIPT_URL')) {
|
||||||
return $baseURL . BASE_SCRIPT_URL;
|
return $baseURL . BASE_SCRIPT_URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $baseURL;
|
return $baseURL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -920,7 +920,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
*
|
*
|
||||||
* Once the environment type is set, it can be checked with {@link Director::isDev()}, {@link Director::isTest()},
|
* Once the environment type is set, it can be checked with {@link Director::isDev()}, {@link Director::isTest()},
|
||||||
* and {@link Director::isLive()}.
|
* and {@link Director::isLive()}.
|
||||||
*
|
*
|
||||||
* @deprecated 3.2 Use the "Director.environment_type" config setting instead
|
* @deprecated 3.2 Use the "Director.environment_type" config setting instead
|
||||||
* @param $et string The environment type: dev, test, or live.
|
* @param $et string The environment type: dev, test, or live.
|
||||||
*/
|
*/
|
||||||
@ -953,19 +953,23 @@ class Director implements TemplateGlobalProvider {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* This function will return true if the site is in a live environment.
|
* This function will return true if the site is in a live environment.
|
||||||
* For information about environment types, see {@link Director::$environment_type}.
|
* For information about environment types, see {@link Director::set_environment_type()}.
|
||||||
|
*
|
||||||
|
* @param $skipDatabase Skips database checks for current login permissions if set to TRUE,
|
||||||
|
* which is useful for checks happening before the database is functional.
|
||||||
*/
|
*/
|
||||||
public static function isLive() {
|
public static function isLive($skipDatabase = false) {
|
||||||
return !(Director::isDev() || Director::isTest());
|
return !(Director::isDev($skipDatabase) || Director::isTest($skipDatabase));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will return true if the site is in a development environment.
|
* This function will return true if the site is in a development environment.
|
||||||
* For information about environment types, see {@link Director::$environment_type}.
|
* For information about environment types, see {@link Director::set_environment_type()}.
|
||||||
* @param $dontTouchDB If true, the database checks are not performed, which allows certain DB checks
|
*
|
||||||
* to not fail before the DB is ready. If false (default), DB checks are included.
|
* @param $skipDatabase Skips database checks for current login permissions if set to TRUE,
|
||||||
|
* which is useful for checks happening before the database is functional.
|
||||||
*/
|
*/
|
||||||
public static function isDev($dontTouchDB = false) {
|
public static function isDev($skipDatabase = false) {
|
||||||
// This variable is used to supress repetitions of the isDev security message below.
|
// This variable is used to supress repetitions of the isDev security message below.
|
||||||
static $firstTimeCheckingGetVar = true;
|
static $firstTimeCheckingGetVar = true;
|
||||||
|
|
||||||
@ -981,7 +985,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use ?isDev=1 to get development access on the live server
|
// Use ?isDev=1 to get development access on the live server
|
||||||
if(!$dontTouchDB && !$result && isset($_GET['isDev'])) {
|
if(!$skipDatabase && !$result && isset($_GET['isDev'])) {
|
||||||
if(Security::database_is_ready()) {
|
if(Security::database_is_ready()) {
|
||||||
if($firstTimeCheckingGetVar && !Permission::check('ADMIN')){
|
if($firstTimeCheckingGetVar && !Permission::check('ADMIN')){
|
||||||
BasicAuth::requireLogin("SilverStripe developer access. Use your CMS login", "ADMIN");
|
BasicAuth::requireLogin("SilverStripe developer access. Use your CMS login", "ADMIN");
|
||||||
@ -1005,11 +1009,14 @@ class Director implements TemplateGlobalProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will return true if the site is in a test environment.
|
* This function will return true if the site is in a test environment.
|
||||||
* For information about environment types, see {@link Director::$environment_type}.
|
* For information about environment types, see {@link Director::set_environment_type()}.
|
||||||
|
*
|
||||||
|
* @param $skipDatabase Skips database checks for current login permissions if set to TRUE,
|
||||||
|
* which is useful for checks happening before the database is functional.
|
||||||
*/
|
*/
|
||||||
public static function isTest() {
|
public static function isTest($skipDatabase = false) {
|
||||||
// Use ?isTest=1 to get test access on the live server, or explicitly set your environment
|
// Use ?isTest=1 to get test access on the live server, or explicitly set your environment
|
||||||
if(isset($_GET['isTest'])) {
|
if(!$skipDatabase && isset($_GET['isTest'])) {
|
||||||
if(Security::database_is_ready()) {
|
if(Security::database_is_ready()) {
|
||||||
BasicAuth::requireLogin("SilverStripe developer access. Use your CMS login", "ADMIN");
|
BasicAuth::requireLogin("SilverStripe developer access. Use your CMS login", "ADMIN");
|
||||||
$_SESSION['isTest'] = $_GET['isTest'];
|
$_SESSION['isTest'] = $_GET['isTest'];
|
||||||
@ -1017,10 +1024,13 @@ class Director implements TemplateGlobalProvider {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(self::isDev()) return false;
|
|
||||||
|
|
||||||
if(Config::inst()->get('Director', 'environment_type')) {
|
if(self::isDev($skipDatabase)) {
|
||||||
return Config::inst()->get('Director', 'environment_type') == 'test';
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(self::$environment_type) {
|
||||||
|
return self::$environment_type == 'test';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are running on one of the test servers
|
// Check if we are running on one of the test servers
|
||||||
|
@ -16,6 +16,8 @@ class SS_Backtrace {
|
|||||||
'mysql_connect',
|
'mysql_connect',
|
||||||
'mssql_connect',
|
'mssql_connect',
|
||||||
'pg_connect',
|
'pg_connect',
|
||||||
|
array('mysqli', 'mysqli'),
|
||||||
|
array('mysqli', 'select_db'),
|
||||||
array('DB', 'connect'),
|
array('DB', 'connect'),
|
||||||
array('Security', 'check_default_admin'),
|
array('Security', 'check_default_admin'),
|
||||||
array('Security', 'encrypt_password'),
|
array('Security', 'encrypt_password'),
|
||||||
|
@ -129,7 +129,7 @@ class Deprecation {
|
|||||||
*/
|
*/
|
||||||
public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD) {
|
public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD) {
|
||||||
// Never raise deprecation notices in a live environment
|
// Never raise deprecation notices in a live environment
|
||||||
if(Director::isLive()) return;
|
if(Director::isLive(true)) return;
|
||||||
|
|
||||||
$checkVersion = self::$version;
|
$checkVersion = self::$version;
|
||||||
// Getting a backtrace is slow, so we only do it if we need it
|
// Getting a backtrace is slow, so we only do it if we need it
|
||||||
|
@ -72,6 +72,10 @@ class DevelopmentAdmin extends Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Backwards compat: Default to "draft" stage, which is important
|
||||||
|
// for tasks like dev/build which call DataObject->requireDefaultRecords(),
|
||||||
|
// but also for other administrative tasks which have assumptions about the default stage.
|
||||||
|
Versioned::reading_stage('Stage');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
|
35
docs/en/changelogs/3.0.9.md
Normal file
35
docs/en/changelogs/3.0.9.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# 3.0.9
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
### Default current Versioned "stage" to "Live" rather than "Stage"
|
||||||
|
|
||||||
|
Previously only the controllers responsible for page and CMS display
|
||||||
|
(`LeftAndMain` and `ContentController`) explicitly set a stage through
|
||||||
|
`Versioned::choose_site_stage()`. Unless this method is called,
|
||||||
|
the default stage will be "Stage", showing draft content.
|
||||||
|
Any direct subclasses of `Controller` interacting with "versioned" objects
|
||||||
|
are vulnerable to exposing unpublished content, unless `choose_site_stage()`
|
||||||
|
is called explicitly in their own logic.
|
||||||
|
|
||||||
|
In order to provide more secure default behaviour, we have changed
|
||||||
|
`choose_site_stage()` to be called on all requests, defaulting to the "Live" stage.
|
||||||
|
If your logic relies on querying draft content, use `Versioned::reading_stage('Stage')`.
|
||||||
|
|
||||||
|
Important: The `choose_site_stage()` call only deals with setting the default stage,
|
||||||
|
and doesn't check if the user is authenticated to view it. As with any other controller logic,
|
||||||
|
please use `DataObject->canView()` to determine permissions.
|
||||||
|
|
||||||
|
:::php
|
||||||
|
class MyController extends Controller {
|
||||||
|
private static $allowed_actions = array('showpage');
|
||||||
|
public function showpage($request) {
|
||||||
|
$page = Page::get()->byID($request->param('ID'));
|
||||||
|
if(!$page->canView()) return $this->httpError(401);
|
||||||
|
// continue with authenticated logic...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### API Changes
|
||||||
|
|
||||||
|
* 2013-08-03 [0e7231f](https://github.com/silverstripe/sapphire/commit/0e7231f) Disable discontinued Google Spellcheck in TinyMCE (Ingo Schommer)
|
@ -2,6 +2,34 @@
|
|||||||
|
|
||||||
## Upgrading
|
## Upgrading
|
||||||
|
|
||||||
|
### Default current Versioned "stage" to "Live" rather than "Stage"
|
||||||
|
|
||||||
|
Previously only the controllers responsible for page and CMS display
|
||||||
|
(`LeftAndMain` and `ContentController`) explicitly set a stage through
|
||||||
|
`Versioned::choose_site_stage()`. Unless this method is called,
|
||||||
|
the default stage will be "Stage", showing draft content.
|
||||||
|
Any direct subclasses of `Controller` interacting with "versioned" objects
|
||||||
|
are vulnerable to exposing unpublished content, unless `choose_site_stage()`
|
||||||
|
is called explicitly in their own logic.
|
||||||
|
|
||||||
|
In order to provide more secure default behaviour, we have changed
|
||||||
|
`choose_site_stage()` to be called on all requests, defaulting to the "Live" stage.
|
||||||
|
If your logic relies on querying draft content, use `Versioned::reading_stage('Stage')`.
|
||||||
|
|
||||||
|
Important: The `choose_site_stage()` call only deals with setting the default stage,
|
||||||
|
and doesn't check if the user is authenticated to view it. As with any other controller logic,
|
||||||
|
please use `DataObject->canView()` to determine permissions.
|
||||||
|
|
||||||
|
:::php
|
||||||
|
class MyController extends Controller {
|
||||||
|
private static $allowed_actions = array('showpage');
|
||||||
|
public function showpage($request) {
|
||||||
|
$page = Page::get()->byID($request->param('ID'));
|
||||||
|
if(!$page->canView()) return $this->httpError(401);
|
||||||
|
// continue with authenticated logic...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
### Treedropdownfield showsearch defaults to true
|
### Treedropdownfield showsearch defaults to true
|
||||||
The showSearch option of TreedropdownField is now set to true by default. This is to provide a fallback ui for when children of a tree node fail to render (due to too many children). You may set search as false when initializing a TreedropdownField, or afterwards:
|
The showSearch option of TreedropdownField is now set to true by default. This is to provide a fallback ui for when children of a tree node fail to render (due to too many children). You may set search as false when initializing a TreedropdownField, or afterwards:
|
||||||
|
|
||||||
|
@ -157,6 +157,33 @@ The `$Content` variable contain the published content by default,
|
|||||||
and only preview draft content if explicitly requested (e.g. by the "preview" feature in the CMS).
|
and only preview draft content if explicitly requested (e.g. by the "preview" feature in the CMS).
|
||||||
If you want to force a specific stage, we recommend the `Controller->init()` method for this purpose.
|
If you want to force a specific stage, we recommend the `Controller->init()` method for this purpose.
|
||||||
|
|
||||||
|
### Controllers
|
||||||
|
|
||||||
|
The current stage for each request is determined by `VersionedRequestFilter` before
|
||||||
|
any controllers initialize, through `Versioned::choose_site_stage()`.
|
||||||
|
It checks for a `Stage` GET parameter, so you can force
|
||||||
|
a draft stage by appending `?stage=Stage` to your request. The setting is "sticky"
|
||||||
|
in the PHP session, so any subsequent requests will also be in draft stage.
|
||||||
|
|
||||||
|
Important: The `choose_site_stage()` call only deals with setting the default stage,
|
||||||
|
and doesn't check if the user is authenticated to view it. As with any other controller logic,
|
||||||
|
please use `DataObject->canView()` to determine permissions, and avoid exposing unpublished
|
||||||
|
content to your users.
|
||||||
|
|
||||||
|
:::php
|
||||||
|
class MyController extends Controller {
|
||||||
|
private static $allowed_actions = array('showpage');
|
||||||
|
public function showpage($request) {
|
||||||
|
$page = Page::get()->byID($request->param('ID'));
|
||||||
|
if(!$page->canView()) return $this->httpError(401);
|
||||||
|
// continue with authenticated logic...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The `ContentController` class responsible for page display already has this built in,
|
||||||
|
so your own `canView()` checks are only necessary in controllers extending directly
|
||||||
|
from the `Controller` class.
|
||||||
|
|
||||||
## Recipes
|
## Recipes
|
||||||
|
|
||||||
### Trapping the publication event
|
### Trapping the publication event
|
||||||
|
Loading…
Reference in New Issue
Block a user