FIX "Draft" stage to fix dev/build, Versioned docs (fixes #2619)

This commit is contained in:
Ingo Schommer 2013-11-01 11:50:49 +01:00
parent d8f29fcc04
commit 65b4407337
3 changed files with 66 additions and 0 deletions

View File

@ -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() {

View 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)

View File

@ -156,6 +156,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