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

Plugins can provide their own config files #7117

Merged
merged 1 commit into from Feb 11, 2015
Merged

Plugins can provide their own config files #7117

merged 1 commit into from Feb 11, 2015

Conversation

mnapoli
Copy link
Contributor

@mnapoli mnapoli commented Feb 1, 2015

See #6609 and #7115

Plugins can provide DI config by putting it in plugin.php.

The file name is completely arbitrary and can be changed… I first went with config.php but some plugins already have a Config class.


private function addPluginConfigs(ContainerBuilder $builder)
{
$plugins = Config::getInstance()->Plugins['Plugins'];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't use the plugin manager here because getActivatedPlugins() returned an empty array (plugins weren't loaded yet).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we load plugins before that or so? We should not really include configs of not activated plugins. Also in tracker mode we have much less plugins that need to be loaded/activated etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is how FrontController::init() goes:

        $tmpPath = StaticContainer::get('path.tmp');

        $directoriesToCheck = array(
            $tmpPath,
            $tmpPath . '/assets/',
            $tmpPath . '/cache/',
            $tmpPath . '/logs/',
            $tmpPath . '/tcpdf/',
            $tmpPath . '/templates_c/',
        );

        Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck);

        $this->handleMaintenanceMode();
        $this->handleProfiler();
        $this->handleSSLRedirection();

        Plugin\Manager::getInstance()->loadPluginTranslations();
        Plugin\Manager::getInstance()->loadActivatedPlugins();

Is it safe to move Plugin\Manager::getInstance()->loadActivatedPlugins(); before the "is writable" check? If yes then that would allow to load the plugins before the container is created.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, it should be safe. Needs to be tested and checked what is done in there, only had a rough look.

Also we need to make sure that during this process DI is not used in the background eg by Config etc? Otherwise it might end in a problem again...

Maybe it makes sense to load "global.php" first... while loading/activating the plugins we also load their definitions. Might be easiest solution that should work and also makes sure we load it only if needed eg while tests are run etc. On "deactivate Plugin" we could maybe unload the definition - if possible. Not really needed though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loading config files (or even changing definitions) after the container has already been used is really risky. If any service or value has already been resolved and injected somewhere, it will not be replaced.

E.g. the logger is injected somewhere, then a plugin changes the logger: the old one is still injected in some places… Leading to inconsistent services.

It might not be a problem directly, and the logger might not be so critical, but it's calling for trouble later with more serious components or config values.

Ideally the container should be built in one step and entries should not be changed after that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually funny thing, path.tmp is an example of something a plugin might change: the CloudAdmin plugin could override that to add the "instance ID" to separate data for each instance.

Today it's using this "instance ID" hack but in the future it could be the plugin that handles that using the container.

Quick n dirty example to illustrate:

// global.php
'path.tmp' => 'tmp',

// CloudAdmin/plugin.php
'path.tmp' => 'tmp/' . $instanceId,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the diff to load plugins before the container.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the diff to load plugins before the container.

It looks like the diff is not updated though? it says Config::getInstance()->Plugins['Plugins'];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep after the discussions (below) I went back to the initial solution

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not yet loaded in the correct order, is it?

@mnapoli mnapoli mentioned this pull request Feb 1, 2015
@mnapoli mnapoli added Enhancement For new feature suggestions that enhance Matomo's capabilities or add a new report, new API etc. c: Platform For Matomo platform changes that aren't impacting any of our APIs but improve the core itself. labels Feb 1, 2015

foreach ($plugins as $plugin) {
$file = Manager::getPluginsDirectory() . $plugin . '/plugin.php';
if (file_exists($file)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the config already cached or do we do this on each request? Can we name it maybe config.php or so? Would be maybe more intuitive for developers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said in the PR config.php wasn't possible.

There is no cache for now (well there is the ArrayCache but of course not persistent between requests).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have a cache at some point, especially re tracking.

Can we maybe rename/move the existing Config classes? Or check whether that file actually returns something and if not, ignore it? We will probably have this convention for a while so might be worth it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the file be located in a config folder, ie plugins/MyPlugin/config/config.php? Ie, mirror the top-level folder structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented plugins/MyPlugin/config.php, see the diff. Not the most efficient piece of code ever but I guess the opcache should make it a non-problem.

I like having config.php at the root of the plugin. But if the change is really not efficient, we could move it to a sub-directory.

But for 3.0 we could say config.php must be a config file, move your class elsewhere. In the meantime we keep BC. So the current Config classes would be sort of "deprecated".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diosmosis haven't thought of that. Actually I'd be 👍 We always try to use same structure already (eg with other folders Columns, tests/UI and tests/*, Tracker, Visualization, ... ) so would make sense. I'm sure we'll have a generator for this at some point so it wouldn't matter when it is in a config directory. Would also allow to add maybe other config entries if needed. Maybe the config folder would be also useful if we allow to provide something like config-dev.php or config/environment/dev.php that will be automatically used for development etc?

/config.php would be otherwise ok for me as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also allow to add maybe other config entries if needed. Maybe the config folder would be also useful if we allow to provide something like config-dev.php or config/environment/dev.php that will be automatically used for development etc?

Great point, I'm +1 with that idea then, I'll move again to config/config.php.

@mnapoli
Copy link
Contributor Author

mnapoli commented Feb 4, 2015

FYI it turns out there's the same problem than with the FrontController all over the place: there is no guarantee that plugins are loaded when the container is called.

I'm trying to find a proper solution to always init the plugins before the container in all environments (web, console, tests, archive.php, tracker, …)

@mnapoli mnapoli added the Pull Request WIP Indicates the current pull request is still work in progress and not ready yet for a review. label Feb 4, 2015
@mnapoli mnapoli self-assigned this Feb 4, 2015
@mnapoli
Copy link
Contributor Author

mnapoli commented Feb 5, 2015

After some discussions:

  • we include plugin config files whether the plugin is yet loaded or not (we don't need the plugin to be loaded to include its config)
    • that means that there is no dependency from the container to the plugin manager, so plugins can be loaded (or not), the container still has all the needed configs
  • for the tracker, only some plugins are loaded, however we include all config files (because some plugin config files could affect options for the tracker app, so there's no reason not to include all files)

TL/DR: problems should be solved!

@mnapoli mnapoli removed the Pull Request WIP Indicates the current pull request is still work in progress and not ready yet for a review. label Feb 5, 2015
@tsteur
Copy link
Member

tsteur commented Feb 5, 2015

Just to be sure we do load only the config for activated plugins right? The wording that we currently have is a bit confusing since loaded can be different to activated

@mnapoli
Copy link
Contributor Author

mnapoli commented Feb 5, 2015

Ah right.

Basically I'm including config file for these Config::getInstance()->Plugins['Plugins'] which should be the activated plugins. Here is the Plugin\Manager method for reference:

    public function loadActivatedPlugins()
    {
        $pluginsToLoad = Config::getInstance()->Plugins['Plugins'];
        $this->loadPlugins($pluginsToLoad);
    }

@tsteur
Copy link
Member

tsteur commented Feb 5, 2015

Yep. I was thinking a check whether they are also installed might be needed but a plugin can't be activated without being installed so should be all good

@mnapoli mnapoli removed their assignment Feb 5, 2015
@mattab mattab added this to the Piwik 2.11.0 milestone Feb 9, 2015
@mattab mattab added the Pull Request WIP Indicates the current pull request is still work in progress and not ready yet for a review. label Feb 9, 2015
@mattab
Copy link
Member

mattab commented Feb 9, 2015

Hey @tsteur could you confirm/merge this one? (looks good to me)

@tsteur
Copy link
Member

tsteur commented Feb 9, 2015

I think this part is missing to make sure plugin configs are loaded in correct order: https://github.com/piwik/piwik/blob/2.11.0-b3/core/Plugin/Manager.php#L1267-L1276

Also it would be nice to have it cached so that we do not do the file_exists etc. all the time but this can be a following task.

$plugins = $this->sortPluginsSameOrderAsGlobalConfig($plugins);

return $plugins;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tsteur I have added this method but it kinda duplicates this one just above:

    public function getActivatedPlugins()
    {
        return $this->pluginsToLoad;
    }

However replacing the existing method by the one I added just blew up everything… I think it's simply that the existing one has a bad name (it doesn't return the activated plugins, it returns the ones the plugin manager is supposed to load). I could rename it from getActivatedPlugins() to getPluginsToLoad() if it makes the diff any better.

@mnapoli
Copy link
Contributor Author

mnapoli commented Feb 9, 2015

Done, please see the inline comment for more details.

mattab pushed a commit that referenced this pull request Feb 11, 2015
Plugins can provide their own config files
@mattab mattab merged commit 5320a48 into master Feb 11, 2015
@tsteur
Copy link
Member

tsteur commented Feb 11, 2015

Is it actually done? Not sure, I linked to makePluginsToLoad which also handles doLoadAlwaysActivatedPlugins. I think the newly added code only handles sortPluginsSameOrderAsGlobalConfig.

@mnapoli
Copy link
Contributor Author

mnapoli commented Feb 11, 2015

makePluginsToLoad which also handles doLoadAlwaysActivatedPlugins

Yes I figured that's because makePluginsToLoad($pluginsToLoad) can be asked to load any plugin list (e.g. used in tests). So we want to be sure that it's loading the one we should always load if we forgot about them. But in our case we are taking the list from the ini config and general.ini.php so unless somebody changed that file (in which case who knows what else has been changed) then the "plugins to always load" will not be messed up?

@tsteur
Copy link
Member

tsteur commented Feb 11, 2015

In case someone messes around with the config or whatever it would maybe make sure Piwik still works. I reckon it is not necessarily needed though it could be a nice to have. Also not sure for what it will be used in the future... Up to you

@mnapoli mnapoli deleted the plugin-config branch February 11, 2015 21:05
mnapoli added a commit that referenced this pull request Feb 11, 2015
@mnapoli
Copy link
Contributor Author

mnapoli commented Feb 11, 2015

I've updated the code on master.

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. Enhancement For new feature suggestions that enhance Matomo's capabilities or add a new report, new API etc. Pull Request WIP Indicates the current pull request is still work in progress and not ready yet for a review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants