mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
204 lines
8.3 KiB
Markdown
204 lines
8.3 KiB
Markdown
# 4.2.0
|
|
|
|
## Overview {#overview}
|
|
|
|
* Disable session-based stage setting in `Versioned` (see [#1578](https://github.com/silverstripe/silverstripe-cms/issues/1578))
|
|
* Deprecated `FunctionalTest::useDraftSite()`. You should use querystring args instead for setting stage.
|
|
|
|
## Upgrading {#upgrading}
|
|
|
|
### App folder name
|
|
|
|
The standard 'mysite' code naming convention has changed in 4.2. Although existing sites can continue
|
|
to use 'mysite/code` to store their base project code, the recommendation and new default is to
|
|
store code in `app/src`.
|
|
|
|
Additionally, we reinforce the recommendation to use psr-4 autoloading in your project to speed up
|
|
class loading.
|
|
|
|
In order to upgrade a site to use `app/src` folder:
|
|
|
|
- Rename the folder `mysite` to `app` and `code` to `src`.
|
|
- Update your `app/_config/mysite.yml` config to the below:
|
|
|
|
```yaml
|
|
---
|
|
Name: myproject
|
|
---
|
|
SilverStripe\Core\Manifest\ModuleManifest:
|
|
project: app
|
|
```
|
|
|
|
- add psr-4 for your root project files and namespace. An example `composer.json` below
|
|
shows how this might look:
|
|
|
|
```json
|
|
{
|
|
"autoload": {
|
|
"psr-4": {
|
|
"TractorCow\\MyWebsite\\": "app/src/"
|
|
},
|
|
"classmap": [
|
|
"app/src/Page.php",
|
|
"app/src/PageController.php"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
- Ensure you flush your site with `?flush=all`
|
|
|
|
Note: In 5.0 the app folder will be fixed to `app` and cannot be soft-coded via `mysite.yml`
|
|
|
|
### 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
|
|
```
|
|
|
|
Check our [versioning docs](/developer_guides/model/versioning#controllers)
|
|
for more details.
|
|
|
|
### New Versioned API
|
|
|
|
The following methods have been added to [api:SilverStripe\Versioned\Versioned] class:
|
|
|
|
* `withVersionedMode()` Allows users to execute a closure which may internally modify
|
|
the current stage, but will guarantee these changes are reverted safely on return.
|
|
Helpful when temporarily performing a task in another stage or view mode.
|
|
* `get_draft_site_secured()` / `set_draft_site_secured()` Enables the explicit toggle
|
|
of draft site security. By setting this to false, you can expose a draft mode to
|
|
unauthenticated users. Replaces `unsecuredDraftSite` session var.
|
|
* `get_default_reading_mode()` / `set_default_reading_mode()` The default reading
|
|
mode is now configurable. Any non-default reading mode must have querystring args
|
|
to be visible. This will be the mode choosen for requests that do not have these args.
|
|
Note that the default mode for CMS is now draft, but is live on the frontend.
|
|
|
|
A new class [api:SilverStripe\Versioned\ReadingMode] has also been added to assist with
|
|
conversion of the reading mode between:
|
|
- Reading mode string
|
|
- DataQuery parameters
|
|
- Querystring parameters
|
|
|
|
### Link tracking
|
|
|
|
SiteTreeLinkTracking has been split and refactored into two extensions, and now
|
|
no longer applies exclusively to `HTMLContent` areas on `SiteTree` objects, but now
|
|
all `DataObject` classes.
|
|
- `SiteTreeLinkTracking` -> Tracks links between any object and SiteTree objects,
|
|
generated from [sitetree_link] shortcodes in html areas.
|
|
- `FileLinkTracking` -> Tracks links between any object and File objects, generated
|
|
from [image] and [file_link] shortcodes in html areas.
|
|
|
|
Note that the `ImageTracking` property has been deprecated in favour of `FileTracking`,
|
|
which includes and tracks non-image files as well.
|
|
|
|
By default `HasBrokenFile` and `HasBrokenLink` properties are still supported, but
|
|
only for `SiteTree` objects by default. Non-SiteTree objects will still have
|
|
both `FileTracking` and `LinkTracking` relations available for tracking
|
|
linked records.
|
|
|
|
In addition, `File::BackLinkTracking()` and `SiteTree::BackLinkTracking()` are now polymorphic,
|
|
and may now both contain non-SiteTree objects. Polymorphic many_many through relations are
|
|
currently experimentally supported.
|
|
|
|
User code which relies on SiteTree-only results for these properties will need to be updated
|
|
to consider other types.
|
|
|
|
Additionally, the `SiteTree_LinkTracking` and `SiteTree_ImageTracking` tables no longer exist,
|
|
and are replaced by the `SiteTreeLink` and `FileLink` many_many through joining classes instead.
|
|
Code which relies on raw SQL queries to these tables will need to be updated.
|
|
|
|
`SiteTreeFileExtension` is deprecated, and has it's functionality baked directly into `File` dataobject.
|
|
|
|
### New upgrader commands
|
|
|
|
Two new commands have been added to the SilverStripe upgrader tool: `environment` and `reorganise`.
|
|
|
|
`environment` allows you to convert your `_ss_environment.php` file to an equivalent `.env` file when migrating a SilverStripe 3 project to SilverStripe 4.
|
|
|
|
`reorganise` renames your `mysite` and `mysite/code` folders to `app` and `app/src`. It also warns you of any occurence of `mysite` in your codebase.
|
|
|
|
```
|
|
cd ~/my-project-root
|
|
upgrade-code environment --write
|
|
upgrade-code reorganise --write
|
|
```
|
|
|
|
### New GridField Action Menu
|
|
|
|
A new `GridField_ActionMenu` is included by default in GridFields configured with `GridFieldConfig_RecordEditor`
|
|
or `GridFieldConfig_RelationEditor`.
|
|
In addition to this `GridFieldDeleteAction` and `GridFieldEditButton` now implement `GridField_ActionMenuItem`,
|
|
this means that any GridField that uses a config of or based on `GridFieldConfig_RecordEditor`
|
|
or `GridFieldConfig_RelationEditor` will have an action menu on each item row with
|
|
the 'Delete/Unlink' and 'Edit' actions moved into it.
|
|
|
|
If you wish to opt out of having this menu and the respective actions moved into it, you can remove the `GridField_ActionMenu`
|
|
component from the config that is passed into your GridField.
|
|
|
|
```php
|
|
// method 1: removing GridField_ActionMenu from a new GridField
|
|
$config = GridFieldConfig_RecordEditor::create();
|
|
$config->removeComponentsByType(GridField_ActionMenu);
|
|
|
|
$gridField = new GridField('Teams', 'Teams', $this->Teams(), $config);
|
|
|
|
// method 2: removing GridField_ActionMenu from an existing GridField
|
|
$gridField->getConfig()->removeComponentsByType(GridField_ActionMenu);
|
|
```
|
|
### Versioned cache segmentation
|
|
|
|
The cache API now maintains separate cache pools for each versioned stage. This prevents users from caching draft data and then exposing it on the live stage.
|
|
|
|
```php
|
|
// Before:
|
|
$cache = Injector::inst()->get(CacheInterface::class . '.myapp');
|
|
Versioned::set_stage(Versioned::DRAFT);
|
|
$cache->set('my_key', 'Some draft content. Not for public viewing yet.');
|
|
Versioned::set_stage(Versioned::LIVE);
|
|
$cache->get('my_key'); // 'Some draft content. Not for public viewing yet'
|
|
|
|
// After:
|
|
$cache = Injector::inst()->get(CacheInterface::class . '.myapp');
|
|
Versioned::set_stage(Versioned::DRAFT);
|
|
$cache->set('my_key', 'Some draft content. Not for public viewing yet.');
|
|
Versioned::set_stage(Versioned::LIVE);
|
|
$cache->get('my_key'); // null
|
|
```
|
|
Data that is not content sensitive can be cached across stages by simply opting out of the segmented cache with the `disable-container` argument.
|
|
|
|
```yaml
|
|
SilverStripe\Core\Injector\Injector:
|
|
Psr\SimpleCache\CacheInterface.myapp:
|
|
factory: SilverStripe\Core\Cache\CacheFactory
|
|
constructor:
|
|
namespace: "MyInsensitiveData"
|
|
args:
|
|
disable-container: true
|
|
```
|