Skip to content
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

Move towards DI for the configuration system #6656

Closed
mnapoli opened this issue Nov 12, 2014 · 6 comments
Closed

Move towards DI for the configuration system #6656

mnapoli opened this issue Nov 12, 2014 · 6 comments
Labels
c: Platform For Matomo platform changes that aren't impacting any of our APIs but improve the core itself. RFC Indicates the issue is a request for comments where the author is looking for feedback.
Milestone

Comments

@mnapoli
Copy link
Contributor

mnapoli commented Nov 12, 2014

This RFC is about discussing changes in the configuration system.

Current status is a mix of:

  • INI files
  • Configuration values in code
  • Objects created in the code

Currently too many things are configured at runtime instead of in a configuration file. For example some things are configured through events. By separating configuration and execution, we end up with a more explicit config and simpler code (ridden of configuration). And we offer more extension points since plugins can override everything in the config (not that they always should ;) ).

Changes proposed:

  • move config options from INI files to DI config
  • move configuration logic (that is in the code) to DI config
  • move objects creation to DI config (or factory objects called by DI config)
  • plugins can provide an optional config file (e.g. named config/config.php?)

List of DI configuration files and their order of inclusion:

  • config/main.php
  • plugins/.../config/config.php (Plugins configs)
  • config/environment.dev.php
  • config/environment.test.php
  • config/config.php (User config)

Environment config allows to override default config and to avoid doing so dynamically it in the code.

Example

When configured to log to file, the logger reads the file name from the Config object.

Then it gets the tmp path and append the filename to it.

Then it gets the Piwik Instance ID and appends it to the path (if not null), which is a special case for the CloudAdmin plugin.

This could be replaced by a config looking like this (this is an abstract config syntax for simplicity):

  • default config:
    • tmpPath = PIWIK_ROOT . '/tmp'
    • logFile = tmpPath . '/logs/piwik.log'

This covers the most common cases. Then if a plugin (e.g. CloudAdmin) wants to customize the path:

  • CloudAdmin config:
    • tmpPath = tmpPath . '/' . instanceId (replace the default config value)
  • User config:
    • instanceId = 123

In the end, we end up with the same result except configuration is separated from execution (the file is not configured in code). The config is more explicit, and also more extensible. No need to add custom "instance ID" code in Piwik Core just for a feature of the CloudAdmin plugin.

Do we keep INI files?

2 things:

  • global/internal Piwik config
  • user config

Global config should be moved to DI config because it's much more powerful so I don't see the point to maintain 2 separated configs.

However user config can be changed by users (obviously) so it might be best if it's as simple as possible (PHP syntax might be too much).

I think DI config files is not incompatible with being simple. If we stick to INI, we'll seriously limit what users can do and override. With DI config they have much more power, yet we can still provide simple configuration options on a use case basis (i.e. no complex PHP syntax).

Quick and dirty example with the logger:

// User config
return [
    'logger' => 'file' // or "stdout" or "database"
];

// Global config
return [
    'Psr\Logger\LoggerInterface' => DI\factory(function ($container) {
        $choice = $container->get('logger');

        if ($choice === 'file') {
            // ...
        } else // ...
    }),
];

Then it still leaves the possibility to advanced users (e.g. Piwik Pro Cloud) to override Psr\Logger\LoggerInterface in their user config to something completely different.

By the way this is how Symfony works with Bundle: you can set up objects manually (e.g. set up your logger and all) or use a bundle that will abstract and simplify the config for you so that you just have to set 1 or 2 options.

@mnapoli mnapoli added c: Platform For Matomo platform changes that aren't impacting any of our APIs but improve the core itself. RFC Indicates the issue is a request for comments where the author is looking for feedback. labels Nov 12, 2014
@mattab
Copy link
Member

mattab commented Nov 15, 2014

cheers for the writeup, it's useful to know your ideas.

Global config should be moved to DI config because it's much more powerful so I don't see the point to maintain 2 separated configs.

here do you mean moving global.ini.php content to the global.php php array? Somehow this sounds quite good to me for one particular reason: we have had problems with users forgetting to put the setting below the right category eg. [Tracker] or [General]. If the format was an array it would make the hierarchy maybe more easy to see.

@mnapoli
Copy link
Contributor Author

mnapoli commented Nov 17, 2014

OK. Just to be sure we understand each other: currently the way to write container entries (i.e. the configuration) is as a flat array. Pseudo-namespacing can be done using any string character, usually . as it's what's used in most Symfony projects for example. Example:

return [
    'scheduled_tasks.min_interval' => 3600,
];

But you can't do that, I don't know if that's what you meant:

return [
    'scheduled_tasks' => [
        'min_interval' => 3600,
    ],
];

(i.e. impossible to inject min_interval, you can only inject the scheduled_tasks array which is usually not what you want)

We could look into a way to change how things work with PHP-DI if we needed to.

@mattab
Copy link
Member

mattab commented Dec 3, 2014

One thing that seems important to me is that we can configure a given Piwik instance and all plugins in the same / one config file (eg. config/config.ini.php)

@mnapoli
Copy link
Contributor Author

mnapoli commented Dec 3, 2014

Would be possible with config/config.php, do you mean you want to keep config.ini.php?

@mattab
Copy link
Member

mattab commented Dec 3, 2014

No don't want to keep config.ini.php in particular, but I think we want toconfigure everything in one simple config file that would only contain the modifications from the "default" config.

@mnapoli
Copy link
Contributor Author

mnapoli commented Dec 3, 2014

ok definitely agree: 1 config file for the user where he can override/customize core and plugins too.

@mnapoli mnapoli closed this as completed Dec 19, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: Platform For Matomo platform changes that aren't impacting any of our APIs but improve the core itself. RFC Indicates the issue is a request for comments where the author is looking for feedback.
Projects
None yet
Development

No branches or pull requests

2 participants