mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Docs for new versioned get param behaviour
See https://github.com/silverstripe/silverstripe-cms/issues/1578
This commit is contained in:
parent
0fe56732af
commit
e6ff8bc681
@ -554,10 +554,93 @@ public function init()
|
||||
|
||||
### 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.
|
||||
The current stage for each request is determined by `VersionedHTTPMiddleware` 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.
|
||||
|
||||
Since SilverStripe 4.2, the current stage setting is no longer "sticky" in the session.
|
||||
Any links presented on the view produced with `?stage=Stage` need to have the same GET parameters in order
|
||||
to retain the stage. If you are using the `SiteTree->Link()` and `Controller->Link()` methods,
|
||||
this is automatically the case for page links, controller links and form actions.
|
||||
|
||||
You can opt for a session base stage setting through the `Versioned.use_session` setting.
|
||||
Warning: This can lead to leaking of unpublished information, if a live URL is viewed in draft mode,
|
||||
and the result is cached due to agressive cache settings (not varying on cookie values).
|
||||
|
||||
*mysite/src/MyObject.php*
|
||||
|
||||
```php
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
use SilverStripe\Control\Controller;
|
||||
|
||||
class MyObject extends DataObject {
|
||||
|
||||
private static $extensions = [
|
||||
Versioned::class
|
||||
];
|
||||
|
||||
public function Link($action = null)
|
||||
{
|
||||
return Injector::inst()->get(MyObjectController::class)->Link($this->ID);
|
||||
}
|
||||
|
||||
public function CustomLink($action = null)
|
||||
{
|
||||
$link = Controller::join_links('custom-route', $this->ID, '?rand=' . rand());
|
||||
$this->extend('updateLink', $link, $action); // updates $link by reference
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*mysite/src/MyObjectController.php*
|
||||
|
||||
```php
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Versioned\VersionedRequestHandlerExtension;
|
||||
|
||||
class MyObjectController extends Controller
|
||||
{
|
||||
private static $extensions = [
|
||||
VersionedRequestHandlerExtension::class
|
||||
];
|
||||
|
||||
public function index(HTTPRequest $request)
|
||||
{
|
||||
$obj = MyObject::get()->byID($request->param('ID'));
|
||||
if (!$obj) {
|
||||
return $this->httpError(404);
|
||||
}
|
||||
|
||||
// Construct view
|
||||
$html = sprintf('<a href="%s">%s</a>', $obj->Link(), $obj->ID);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function Link($action = null)
|
||||
{
|
||||
// Construct link with graceful handling of GET parameters
|
||||
$link = Controller::join_links('my-objects', $action, '?rand=' . rand());
|
||||
|
||||
// Allow Versioned and other extension to update $link by reference
|
||||
$this->extend('updateLink', $link, $action);
|
||||
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*mysite/_config/routes.yml*
|
||||
|
||||
```yml
|
||||
SilverStripe\Control\Director:
|
||||
rules:
|
||||
'my-objects/$ID': 'MyObjectController'
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
The `choose_site_stage()` call only deals with setting the default stage, and doesn't check if the user is
|
||||
|
@ -159,20 +159,23 @@ For more information about templates, inheritance and how to render into views,
|
||||
|
||||
## Link
|
||||
|
||||
Each controller should define a `Link()` method. This should be used to avoid hard coding your routing in views etc.
|
||||
Each controller should define a `Link()` method. This should be used to avoid hard coding your routing in views,
|
||||
as well as give other features in SilverStripe the ability to influence link behaviour.
|
||||
|
||||
**mysite/code/controllers/TeamController.php**
|
||||
|
||||
```php
|
||||
public function Link($action = null)
|
||||
{
|
||||
return Controller::join_links('teams', $action);
|
||||
// Construct link with graceful handling of GET parameters
|
||||
$link = Controller::join_links('teams', $ction);
|
||||
|
||||
// Allow Versioned and other extension to update $link by reference.
|
||||
$this->extend('updateLink', $link, $action);
|
||||
|
||||
return $link;
|
||||
}
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
The [Controller::join_links()](api:SilverStripe\Control\Controller::join_links()) is optional, but makes `Link()` more flexible by allowing an `$action` argument, and concatenates the path segments with slashes. The action should map to a method on your controller.
|
||||
</div>
|
||||
```
|
||||
|
||||
## Related Lessons
|
||||
* [Controller actions/DataObjects as pages](https://www.silverstripe.org/learn/lessons/v4/controller-actions-dataobjects-as-pages-1)
|
||||
|
37
docs/en/04_Changelogs/4.2.0.md
Normal file
37
docs/en/04_Changelogs/4.2.0.md
Normal file
@ -0,0 +1,37 @@
|
||||
# 4.2.0
|
||||
|
||||
## Overview {#overview}
|
||||
|
||||
* Disable session-based stage setting in `Versioned` (see [#1578](https://github.com/silverstripe/silverstripe-cms/issues/1578))
|
||||
|
||||
## Upgrading {#upgrading}
|
||||
|
||||
### Disable session-based stage setting
|
||||
|
||||
When viewing a versioned record (usually pages) in "draft" mode,
|
||||
SilverStripe used to record this mode in the session for further requests.
|
||||
This has the advantage of transparently working on XHR and API requests,
|
||||
as well as authenticated users navigating through other views.
|
||||
|
||||
These subsequent requests no longer carried an explicit `stage` query parameter,
|
||||
which meant the same URL might show draft or live content depending on your session state.
|
||||
While most HTTP caching layers deal gracefully with this variation by disabling
|
||||
any caching when a session cookie is present, there is a small chance
|
||||
that draft content is exposed to unauthenticated users for the lifetime of the cache.
|
||||
|
||||
Due to this potential risk for information leakage,
|
||||
we have decided to only rely on the `stage` query parameter.
|
||||
If you are consistently using the built-in `SiteTree->Link()`
|
||||
and `Controller->Link()` methods to get URLs, this change likely won't affect you.
|
||||
|
||||
If you are manually concatenating URLs to SilverStripe controllers
|
||||
rather than through their `Link()` methods (in custom PHP or JavaScript),
|
||||
or have implemented your own `Link()` methods on controllers exposing
|
||||
versioned objects, you'll need to check your business logic.
|
||||
|
||||
Alternatively, you can opt-out of this security feature via YAML configuration:
|
||||
|
||||
```yml
|
||||
SilverStripe\Versioned\Versioned:
|
||||
use_session: true
|
||||
```
|
Loading…
Reference in New Issue
Block a user