mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Update config documentation
This commit is contained in:
parent
8444a21cbf
commit
e2064b5cc8
@ -42,7 +42,7 @@ config:
|
|||||||
|
|
||||||
|
|
||||||
:::yaml
|
:::yaml
|
||||||
Injector:
|
SilverStripe\Core\Injector\Injector:
|
||||||
DataListFilter.CustomMatch:
|
DataListFilter.CustomMatch:
|
||||||
class: MyVendor/Search/CustomMatchFilter
|
class: MyVendor/Search/CustomMatchFilter
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ also track versioned history.
|
|||||||
:::php
|
:::php
|
||||||
class MyStagedModel extends DataObject {
|
class MyStagedModel extends DataObject {
|
||||||
private staic $extensions = [
|
private staic $extensions = [
|
||||||
"Versioned"
|
Versioned::class
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ can be specified by setting the constructor argument to "Versioned"
|
|||||||
|
|
||||||
:::php
|
:::php
|
||||||
class VersionedModel extends DataObject {
|
class VersionedModel extends DataObject {
|
||||||
private staic $extensions = [
|
private static $extensions = [
|
||||||
"Versioned('Versioned')"
|
"SilverStripe\\ORM\\Versioning\\Versioned('Versioned')"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,14 +63,14 @@ adding a suffix.
|
|||||||
|
|
||||||
* `MyRecord` table: Contains staged data
|
* `MyRecord` table: Contains staged data
|
||||||
* `MyRecord_Live` table: Contains live data
|
* `MyRecord_Live` table: Contains live data
|
||||||
* `MyRecord_versions` table: Contains a version history (new record created on each save)
|
* `MyRecord_Versions` table: Contains a version history (new record created on each save)
|
||||||
|
|
||||||
Similarly, any subclass you create on top of a versioned base will trigger the creation of additional tables, which are
|
Similarly, any subclass you create on top of a versioned base will trigger the creation of additional tables, which are
|
||||||
automatically joined as required:
|
automatically joined as required:
|
||||||
|
|
||||||
* `MyRecordSubclass` table: Contains only staged data for subclass columns
|
* `MyRecordSubclass` table: Contains only staged data for subclass columns
|
||||||
* `MyRecordSubclass_Live` table: Contains only live data for subclass columns
|
* `MyRecordSubclass_Live` table: Contains only live data for subclass columns
|
||||||
* `MyRecordSubclass_versions` table: Contains only version history for subclass columns
|
* `MyRecordSubclass_Versions` table: Contains only version history for subclass columns
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -81,12 +81,12 @@ explicitly request a certain stage through various getters on the `Versioned` cl
|
|||||||
|
|
||||||
:::php
|
:::php
|
||||||
// Fetching multiple records
|
// Fetching multiple records
|
||||||
$stageRecords = Versioned::get_by_stage('MyRecord', 'Stage');
|
$stageRecords = Versioned::get_by_stage('MyRecord', Versioned::DRAFT);
|
||||||
$liveRecords = Versioned::get_by_stage('MyRecord', 'Live');
|
$liveRecords = Versioned::get_by_stage('MyRecord', Versioned::LIVE);
|
||||||
|
|
||||||
// Fetching a single record
|
// Fetching a single record
|
||||||
$stageRecord = Versioned::get_by_stage('MyRecord', 'Stage')->byID(99);
|
$stageRecord = Versioned::get_by_stage('MyRecord', Versioned::DRAFT)->byID(99);
|
||||||
$liveRecord = Versioned::get_by_stage('MyRecord', 'Live')->byID(99);
|
$liveRecord = Versioned::get_by_stage('MyRecord', Versioned::LIVE)->byID(99);
|
||||||
|
|
||||||
### Historical Versions
|
### Historical Versions
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ done via one of several ways:
|
|||||||
See "DataObject ownership" for reference on dependant objects.
|
See "DataObject ownership" for reference on dependant objects.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$record = Versioned::get_by_stage('MyRecord', 'Stage')->byID(99);
|
$record = Versioned::get_by_stage('MyRecord', Versioned::DRAFT)->byID(99);
|
||||||
$record->MyField = 'changed';
|
$record->MyField = 'changed';
|
||||||
// will update `MyRecord` table (assuming Versioned::current_stage() == 'Stage'),
|
// will update `MyRecord` table (assuming Versioned::current_stage() == 'Stage'),
|
||||||
// and write a row to `MyRecord_versions`.
|
// and write a row to `MyRecord_versions`.
|
||||||
@ -144,7 +144,7 @@ Similarly, an "unpublish" operation does the reverse, and removes a record from
|
|||||||
:::php
|
:::php
|
||||||
$record = MyRecord::get()->byID(99); // stage doesn't matter here
|
$record = MyRecord::get()->byID(99); // stage doesn't matter here
|
||||||
// will remove the row from the `MyRecord_Live` table
|
// will remove the row from the `MyRecord_Live` table
|
||||||
$record->deleteFromStage('Live');
|
$record->deleteFromStage(Versioned::LIVE);
|
||||||
|
|
||||||
### Forcing the Current Stage
|
### Forcing the Current Stage
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ is initialized. But it can also be set and reset temporarily to force a specific
|
|||||||
:::php
|
:::php
|
||||||
$origMode = Versioned::get_reading_mode(); // save current mode
|
$origMode = Versioned::get_reading_mode(); // save current mode
|
||||||
$obj = MyRecord::getComplexObjectRetrieval(); // returns 'Live' records
|
$obj = MyRecord::getComplexObjectRetrieval(); // returns 'Live' records
|
||||||
Versioned::set_reading_mode('Stage'); // temporarily overwrite mode
|
Versioned::set_reading_mode(Versioned::DRAFT); // temporarily overwrite mode
|
||||||
$obj = MyRecord::getComplexObjectRetrieval(); // returns 'Stage' records
|
$obj = MyRecord::getComplexObjectRetrieval(); // returns 'Stage' records
|
||||||
Versioned::set_reading_mode($origMode); // reset current mode
|
Versioned::set_reading_mode($origMode); // reset current mode
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ without requiring any custom code.
|
|||||||
:::php
|
:::php
|
||||||
class MyPage extends Page {
|
class MyPage extends Page {
|
||||||
private static $has_many = array(
|
private static $has_many = array(
|
||||||
'Banners' => 'Banner'
|
'Banners' => Banner::class
|
||||||
);
|
);
|
||||||
private static $owns = array(
|
private static $owns = array(
|
||||||
'Banners'
|
'Banners'
|
||||||
@ -189,11 +189,11 @@ without requiring any custom code.
|
|||||||
|
|
||||||
class Banner extends Page {
|
class Banner extends Page {
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
'Versioned'
|
Versioned::class
|
||||||
);
|
);
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'Parent' => 'MyPage',
|
'Parent' => MyPage::class,
|
||||||
'Image' => 'Image',
|
'Image' => Image::class,
|
||||||
);
|
);
|
||||||
private static $owns = array(
|
private static $owns = array(
|
||||||
'Image'
|
'Image'
|
||||||
@ -219,7 +219,7 @@ E.g.
|
|||||||
:::php
|
:::php
|
||||||
class MyParent extends DataObject {
|
class MyParent extends DataObject {
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
'Versioned'
|
Versioned::class
|
||||||
);
|
);
|
||||||
private static $owns = array(
|
private static $owns = array(
|
||||||
'ChildObjects'
|
'ChildObjects'
|
||||||
@ -230,7 +230,7 @@ E.g.
|
|||||||
}
|
}
|
||||||
class MyChild extends DataObject {
|
class MyChild extends DataObject {
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
'Versioned'
|
Versioned::class
|
||||||
);
|
);
|
||||||
private static $owned_by = array(
|
private static $owned_by = array(
|
||||||
'Parent'
|
'Parent'
|
||||||
@ -258,7 +258,7 @@ smaller modifications of the generated `DataList` objects.
|
|||||||
Example: Get the first 10 live records, filtered by creation date:
|
Example: Get the first 10 live records, filtered by creation date:
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$records = Versioned::get_by_stage('MyRecord', 'Live')->limit(10)->sort('Created', 'ASC');
|
$records = Versioned::get_by_stage('MyRecord', Versioned::LIVE)->limit(10)->sort('Created', 'ASC');
|
||||||
|
|
||||||
### Permissions
|
### Permissions
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ E.g.
|
|||||||
:::php
|
:::php
|
||||||
class MyObject extends DataObject {
|
class MyObject extends DataObject {
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
'Versioned'
|
Versioned::class,
|
||||||
);
|
);
|
||||||
|
|
||||||
public function canViewVersioned($member = null) {
|
public function canViewVersioned($member = null) {
|
||||||
@ -325,7 +325,7 @@ E.g.
|
|||||||
:::php
|
:::php
|
||||||
class MyObject extends DataObject {
|
class MyObject extends DataObject {
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
'Versioned'
|
Versioned::class,
|
||||||
);
|
);
|
||||||
private static $non_live_permissions = array('ADMIN');
|
private static $non_live_permissions = array('ADMIN');
|
||||||
}
|
}
|
||||||
@ -348,7 +348,7 @@ to force a specific stage, we recommend the `Controller->init()` method for this
|
|||||||
:::php
|
:::php
|
||||||
public function init() {
|
public function init() {
|
||||||
parent::init();
|
parent::init();
|
||||||
Versioned::set_reading_mode('Stage.Stage');
|
Versioned::set_stage(Versioned::DRAFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ Make sure that after you have modified the `routes.yml` file, that you clear you
|
|||||||
Name: mysiteroutes
|
Name: mysiteroutes
|
||||||
After: framework/routes#coreroutes
|
After: framework/routes#coreroutes
|
||||||
---
|
---
|
||||||
Director:
|
SilverStripe\Control\Director:
|
||||||
rules:
|
rules:
|
||||||
'teams//$Action/$ID/$Name': 'TeamController'
|
'teams//$Action/$ID/$Name': 'TeamController'
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ summary: SilverStripe's YAML based Configuration API for setting runtime configu
|
|||||||
|
|
||||||
SilverStripe comes with a comprehensive code based configuration system through the [api:Config] class. It primarily
|
SilverStripe comes with a comprehensive code based configuration system through the [api:Config] class. It primarily
|
||||||
relies on declarative [YAML](http://en.wikipedia.org/wiki/YAML) files, and falls back to procedural PHP code, as well
|
relies on declarative [YAML](http://en.wikipedia.org/wiki/YAML) files, and falls back to procedural PHP code, as well
|
||||||
as PHP static variables.
|
as PHP static variables. This is provided by the [silverstripe/config](https://github.com/silverstripe/silverstripe-config)
|
||||||
|
library.
|
||||||
|
|
||||||
The Configuration API can be seen as separate from other forms of variables in the SilverStripe system due to three
|
The Configuration API can be seen as separate from other forms of variables in the SilverStripe system due to three
|
||||||
properties API:
|
properties API:
|
||||||
@ -49,19 +50,28 @@ be marked `private static` and follow the `lower_case_with_underscores` structur
|
|||||||
This can be done by calling the static method [api:Config::inst()], like so:
|
This can be done by calling the static method [api:Config::inst()], like so:
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$config = Config::inst()->get('MyClass');
|
$config = Config::inst()->get('MyClass', 'property');
|
||||||
|
|
||||||
Or through the `config()` object on the class.
|
Or through the `config()` object on the class.
|
||||||
|
|
||||||
$config = $this->config();
|
$config = $this->config()->get('property')';
|
||||||
|
|
||||||
There are three public methods available on the instance. `get($class, $variable)`, `remove($class, $variable)` and
|
Note that by default `Config::inst()` returns only an immutable version of config. Use `Config::modify()`
|
||||||
`update($class, $variable, $value)`.
|
if it's necessary to alter class config. This is generally undesirable in most applications, as modification
|
||||||
|
of the config can immediately have performance implications, so this should be used sparingly, or
|
||||||
|
during testing to modify state.
|
||||||
|
|
||||||
<div class="notice" markdown="1">
|
Note that while both objects have similar methods the APIs differ slightly. The below actions are equivalent:
|
||||||
There is no "set" method. It is not possible to completely set the value of a classes' property. `update` adds new
|
|
||||||
values that are treated as the highest priority in the merge, and remove adds a merge mask that filters out values.
|
* `Config::inst()->get('Class', 'property');` or `Class::config()->get('property')`
|
||||||
</div>
|
* `Config::inst()->uninherited('Class', 'property');` or `Class::config()->get('property', Config::UNINHERITED)`
|
||||||
|
* `Config::inst()->exists('Class', 'property');` or `Class::config()->exists('property')`
|
||||||
|
|
||||||
|
And mutable methods:
|
||||||
|
|
||||||
|
* `Config::modify()->merge('Class', 'property', 'newvalue');` or `Class::config()->merge('property', 'newvalue')`
|
||||||
|
* `Config::modify()->set('Class', 'property', 'newvalue');` or `Class::config()->set('property', 'newvalue')`
|
||||||
|
* `Config::modify()->remove('Class', 'property');` or `Class::config()->remove('property')`
|
||||||
|
|
||||||
To set those configuration options on our previously defined class we can define it in a `YAML` file.
|
To set those configuration options on our previously defined class we can define it in a `YAML` file.
|
||||||
|
|
||||||
@ -92,7 +102,7 @@ To use those variables in your application code:
|
|||||||
echo implode(', ', Config::inst()->get('MyClass', 'option_two'));
|
echo implode(', ', Config::inst()->get('MyClass', 'option_two'));
|
||||||
// returns 'Foo, Bar, Baz'
|
// returns 'Foo, Bar, Baz'
|
||||||
|
|
||||||
Config::inst()->update('MyClass', 'option_one', true);
|
Config::inst()->set('MyClass', 'option_one', true);
|
||||||
|
|
||||||
echo Config::inst()->get('MyClass', 'option_one');
|
echo Config::inst()->get('MyClass', 'option_one');
|
||||||
// returns true
|
// returns true
|
||||||
@ -134,7 +144,7 @@ the result will be the higher priority false-ish value.
|
|||||||
|
|
||||||
The locations that configuration values are taken from in highest -> lowest priority order are:
|
The locations that configuration values are taken from in highest -> lowest priority order are:
|
||||||
|
|
||||||
- Any values set via a call to Config#update
|
- Any values set via a call to Config#merge / Config#set
|
||||||
- The configuration values taken from the YAML files in `_config/` directories (internally sorted in before / after
|
- The configuration values taken from the YAML files in `_config/` directories (internally sorted in before / after
|
||||||
order, where the item that is latest is highest priority)
|
order, where the item that is latest is highest priority)
|
||||||
- Any static set on an "additional static source" class (such as an extension) named the same as the name of the property
|
- Any static set on an "additional static source" class (such as an extension) named the same as the name of the property
|
||||||
@ -155,13 +165,13 @@ rather than add.
|
|||||||
'allowed_actions', Config::UNINHERITED
|
'allowed_actions', Config::UNINHERITED
|
||||||
);
|
);
|
||||||
|
|
||||||
They are much simpler. They consist of a list of key / value pairs. When applied against the current composite value
|
Available masks include:
|
||||||
|
|
||||||
- If the composite value is a sequential array, any member of that array that matches any value in the mask is removed
|
* Config::UNINHERITED - Exclude config inherited from parent classes
|
||||||
- If the composite value is an associative array, any member of that array that matches both the key and value of any
|
* Config::EXCLUDE_EXTRA_SOURCES - Exclude config applied by extensions
|
||||||
pair in the mask is removed
|
|
||||||
- If the composite value is not an array, if that value matches any value in the mask it is removed
|
|
||||||
|
|
||||||
|
You can also pass in literal `true` to disable all extra sources, or merge config options with
|
||||||
|
bitwise `|` operator.
|
||||||
|
|
||||||
## Configuration YAML Syntax and Rules
|
## Configuration YAML Syntax and Rules
|
||||||
|
|
||||||
@ -280,11 +290,13 @@ rules contained match.
|
|||||||
You then list any of the following rules as sub-keys, with informational values as either a single value or a list.
|
You then list any of the following rules as sub-keys, with informational values as either a single value or a list.
|
||||||
|
|
||||||
- 'classexists', in which case the value(s) should be classes that must exist
|
- 'classexists', in which case the value(s) should be classes that must exist
|
||||||
- 'moduleexists', in which case the value(s) should be modules that must exist
|
- 'moduleexists', in which case the value(s) should be modules that must exist. This supports either folder
|
||||||
|
name or composer `vendor/name` format.
|
||||||
- 'environment', in which case the value(s) should be one of "live", "test" or "dev" to indicate the SilverStripe
|
- 'environment', in which case the value(s) should be one of "live", "test" or "dev" to indicate the SilverStripe
|
||||||
mode the site must be in
|
mode the site must be in
|
||||||
- 'envvarset', in which case the value(s) should be environment variables that must be set
|
- 'envvarset', in which case the value(s) should be environment variables that must be set
|
||||||
- 'constantdefined', in which case the value(s) should be constants that must be defined
|
- 'constantdefined', in which case the value(s) should be constants that must be defined
|
||||||
|
- 'envorconstant' A variable which should be defined either via environment vars or constants
|
||||||
|
|
||||||
For instance, to add a property to "foo" when a module exists, and "bar" otherwise, you could do this:
|
For instance, to add a property to "foo" when a module exists, and "bar" otherwise, you could do this:
|
||||||
|
|
||||||
@ -303,19 +315,23 @@ For instance, to add a property to "foo" when a module exists, and "bar" otherwi
|
|||||||
property: 'bar'
|
property: 'bar'
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Multiple conditions of the same type can be declared via array format
|
||||||
|
|
||||||
|
|
||||||
|
:::yaml
|
||||||
|
---
|
||||||
|
Only:
|
||||||
|
moduleexists:
|
||||||
|
- 'silverstripe/blog'
|
||||||
|
- 'silverstripe/lumberjack'
|
||||||
|
|
||||||
|
|
||||||
<div class="alert" markdown="1">
|
<div class="alert" markdown="1">
|
||||||
When you have more than one rule for a nested fragment, they're joined like
|
When you have more than one rule for a nested fragment, they're joined like
|
||||||
`FRAGMENT_INCLUDED = (ONLY && ONLY) && !(EXCEPT && EXCEPT)`.
|
`FRAGMENT_INCLUDED = (ONLY && ONLY) && !(EXCEPT && EXCEPT)`.
|
||||||
That is, the fragment will be included if all Only rules match, except if all Except rules match.
|
That is, the fragment will be included if all Only rules match, except if all Except rules match.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="alert" markdown="1">
|
|
||||||
Due to YAML limitations, having multiple conditions of the same kind (say, two `EnvVarSet` in one "Only" block)
|
|
||||||
will result in only the latter coming through.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
## API Documentation
|
## API Documentation
|
||||||
|
|
||||||
* [api:Config]
|
* [api:Config]
|
||||||
|
@ -959,6 +959,26 @@ to update those with the appropriate function or config call. See
|
|||||||
[CMS architecture](/developer_guides/customising_the_admin_interface/cms-architecture#the-admin-url) for language
|
[CMS architecture](/developer_guides/customising_the_admin_interface/cms-architecture#the-admin-url) for language
|
||||||
specific functions.
|
specific functions.
|
||||||
|
|
||||||
|
|
||||||
|
#### Upgrading Config API usages
|
||||||
|
|
||||||
|
Performance optimisations have been made to Config which, under certain circumstances, require developer
|
||||||
|
care when modifying or caching config values. The top level config object is now immutable on application
|
||||||
|
bootstrap, and requires a developer to invoke `Config::modify()` to make mutable prior to modification.
|
||||||
|
This will immediately have a slight performance hit, so should be done sparingly, and avoided at all
|
||||||
|
if possible in performance intensive applications.
|
||||||
|
|
||||||
|
In addition, the `Config::inst()->update()` method is deprecated, and replaced with `Config::modify()->set()` and
|
||||||
|
`Config::modify()->merge()` to respectively replace and merge config.
|
||||||
|
|
||||||
|
When config is merged (either via modification or merged between yml blocks) falsey-values (including nulls)
|
||||||
|
now replace any prior values (even arrays).
|
||||||
|
|
||||||
|
One removed feature is the `Config::FIRST_SET` option. Either use uninherited config directly on the class
|
||||||
|
directly, or use the inherited config lookup. As falsey values now overwrite all parent class values, it is
|
||||||
|
now generally safer to use the default inherited config, where in the past you would need to use `FIRST_SET`.
|
||||||
|
|
||||||
|
|
||||||
## <a name="api-changes"></a>API Changes
|
## <a name="api-changes"></a>API Changes
|
||||||
|
|
||||||
### <a name="overview-general"></a>General and Core API
|
### <a name="overview-general"></a>General and Core API
|
||||||
|
Loading…
Reference in New Issue
Block a user