-
Notifications
You must be signed in to change notification settings - Fork 824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Config API options #6611
Comments
Vote: Config::get() - InheritanceBy default, getting a config value will automatically merge down from child classes to parent classes. Non-array values will overwrite. This can be controlled via one of the options: Config::INHERITED - Merge all config in the hierarchy (default).
|
Vote: Config::update() - CachingThis simply merges any array values with the current config, or replaces non-array values. However, these values are not cached, and are simply merged into the current config. With the new caching system, we could allow this method to take a callable, which could be invoked by the cache backend. E.g. Config::inst()->update(SiteTree::class, 'db', function() {
return $this->buildFields();
}); Please vote using:
|
Vote: Config::update() - Merge behaviourCurrently Config::update() will default to merging array configs together, rather than replacing. Potentially, it would be better to either add an options to update() to control this. E.g. Config::MERGE (merge array values only) or Config::REPLACE. Please vote using:
|
Vote: Extensions - Extra ConfigExtension classes can implement an get_extra_config() method, which allows config to be dynamically generated for extended classes. Without this feature, config can only be applied to extended classes via actual This is used in a few places in core, so substituting this will require some further discussion. Please vote using:
|
Vote: Custom user-defined config source - CacheableAs an alternative to the above, we could define a E.g.
Please vote using:
|
Vote: Falsey valuesThere has been a long-standing convention in config that falsey values cannot be overridden easily in config. e.g. ---
Name: base
---
Class:
option:
Key1: null
Key2: 'test'
---
Name: extra
---
Class
option:
Key1: 'new key1'
Key2: null Config::inst()->get('Class', 'option') would be give
We propose fixing this so that later values, even if empty, replace prior values. I.e.
Related issue: #3272 Please vote using:
|
Unlocked for voting! |
I have a branch of cms and framework which i'll share when I can, but its outdated. It already covers a few things below - all I that's left to do is fix the tests (there's a lot failing). Config::get() - Inheritance Removing others might be too much of a change. I would support it but doubt it would be realistic to include in this change. Config::update() - Caching Further to this, if this was something we needed (updating on key changes), I think it should be implemented via an event system rather than callbacks which could become hard to maintain. Config::update() - Merge behaviour Extensions - Extra Config Custom user-defined config source - Cacheable Also, having the logic in PHP makes it easy for people to call things before they're ready. Falsey values |
A few quick comments for now @tractorcow
|
Hm, this puts me into a bit of a corner, because saying there are no allowed sources for config at all (other than yml / private statics) removes a lot of use cases that we currently rely on. I've attempted to suggest various alternatives to this, but it doesn't feel as though any of them are accepted. Can we discuss what "the" solution should look like in case an application has a need for generated / extensible config? Do we need some kind of new "Extension, but for config" api? |
Rather than an interface and requiring a class manifest, we could push additional config sources. mysite/_config.php <?php
use SilverStripe\Core\Config\ConfigLoader;
$configSource = new MyModuleSource();
ConfigLoader::instance()->getManifest()->registerSource($configSource); mysite/code/MyModuleSource.php <?php
use SilverStripe\Core\Config\ConfigSource;
class MyModuleSource implements ConfigSource {
// Getter only?
public function getConfig()
{
return [
'SiteTree' => [
'db' => $this->buildfields(),
],
];
}
// Decorate existing config?
public function updateConfig(&$config)
{
$config['SiteTree']['db'] = array_merge($config['SiteTree']['db'], $this->buildFields());
}
} Additional config sources could be cached. Additionally, we could leave Config::inst()->update() calls uncached, and have these affect only the current request (status quo). |
Actually, we could load in additional sources via yml, given that the static and yml loaders are loaded first. SilverStripe\Core\Config\ConfigLoader:
config_sources:
- MyModuleSource |
Maybe it would help to use an example. FulltextSearchable extension generates a dynamic
How would this be approached with the new config system? |
@micmania1 quick question for you over the weekend; Is ConfigCollection::get() supposed to return the value, or the value + metadata? It looks like ConfigCollection::set() doesn't include the metadata. Possible bug? public function set($key, $value, $metadata = []) {
...
$this->config[$key] = $value;
} |
I've just pushed 3 new commits which includes some fixes: https://github.com/micmania1/silverstripe-config/commits/master |
Thanks, I have a fork I'm playing around with that I'll rebase on. :D |
I've had a chat with @sminnee about some of the concerns around caching / mutable configs. We've decided to split the current Config class into ImmutableConfig and MutableConfig, where the former is the default. Trying to mix inheritance, caching, and mutability wasn't ending up as maintainable or performant code. Applications that wish to make local modifications to config (via update / remove) will need to use MutableConfig. Additionally, we're going to move INHERITED out of the Config layer (and caching level) and require users to opt-into class inheritance to get a hierarchal list of configs. That and FIRST_SET being gone means a simpler config back-end. :) We'll probably add it in as optional-api to Config_ForClass. |
Proof of concept of split at open-sausages@0a2b550 Includes re-implementation of the missing update() / remove() functions, although in this case I've split update() into set() and merge(), and deprecated the original. |
closed with #6641 |
References
Note: I'm going to lock this temporarily until I finish preparing the questions for voting. :)
Introduction
We are looking to move the config system away from the current backend and replace it with one built by @micmania1 https://github.com/micmania1/silverstripe-config
The purpose of this RFC is not to discuss so much the details regarding the implementation of this backend, but the necessary API available to the user.
The goal of this RFC will be to build an idea of which features users rely on, and which features can be either trimmed or completely removed.
Following this RFC I will leave a series of comments that users can vote on individually.
Proposal
Config::get() - Inheritance
Vote link: #6611 (comment)
By default, getting a config value will automatically merge down from child classes to parent classes. Non-array values will overwrite.
This can be controlled via one of the options:
Please vote using:
Config::update() - Caching
Vote link: #6611 (comment)
This simply merges any array values with the current config, or replaces non-array values.
However, these values are not cached, and are simply merged into the current config.
With the new caching system, we could allow this method to take a callable, which could be invoked by the cache backend. E.g.
Please vote using:
Config::update() - Merge behaviour
Vote link: #6611 (comment)
Currently Config::update() will default to merging array configs together, rather than replacing. Potentially, it would be better to either add an options to update() to control this. E.g. Config::MERGE (merge array values only) or Config::REPLACE.
Please vote using:
Extensions - Extra Config
Vote link: #6611 (comment)
Extension classes can implement an get_extra_config() method, which allows config to be dynamically generated for extended classes.
Without this feature, config can only be applied to extended classes via actual
private statics
on those extensions, or via yml.This is used in a few places in core, so substituting this will require some further discussion.
Please vote using:
Custom user-defined config source - Cacheable
Vote link: #6611 (comment)
As an alternative to the above, we could define a
ConfigSource
interface, which could be implemented by any class, and this config could be cacheable.E.g.
Please vote using:
Falsey values
Vote link: #6611 (comment)
There has been a long-standing convention in config that falsey values cannot be overridden easily in config. e.g.
Config::inst()->get('Class', 'option') would be give
We propose fixing this so that later values, even if empty, replace prior values. I.e.
Related issue: #3272
Please vote using:
The text was updated successfully, but these errors were encountered: