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

PluginInterface::config() #11039

Merged
merged 2 commits into from
Apr 28, 2022
Merged

PluginInterface::config() #11039

merged 2 commits into from
Apr 28, 2022

Conversation

brandonkelly
Copy link
Member

@brandonkelly brandonkelly commented Apr 28, 2022

This adds a new static config() method to craft\base\PluginInterface, giving plugins a way to define their configuration.

Plugins that have their own additional components (e.g. services) should start using this to define them:

public static function config(): array
{
    return [
        'components' => [
            'myComponent' => ['class' => MyComponent::class],
            // ...
        ],
    ];
}

Doing that enables projects to customize the components as needed, by overriding craft\services\Plugins::$pluginConfigs in config/app.php:

return [
    'components' => [
        'plugins' => [
            'pluginConfigs' => [
                'my-plugin' => [
                    'components' => [
                        'myComponent' => [
                            'myProperty' => 'foo',
                            // ...
                        ],
                    ],
                ],
            ],
        ],
    ],
];

@brandonkelly brandonkelly requested a review from a team as a code owner April 28, 2022 17:20
@brandonkelly brandonkelly merged commit a9e0493 into 4.0 Apr 28, 2022
@brandonkelly brandonkelly deleted the feature/plugin-configs branch April 28, 2022 17:43
@michaelrog
Copy link

michaelrog commented Apr 28, 2022

Nice. Curiously, why not place these overrides in each plugin's config file? (Seems like it might be slightly more tidy to keep container overrides close in code to plugin settings. The structure of the plugin config file would need to change slightly, perhaps by moving settings overrides into an explicit settings key... Or even a settings component...)

Or, if we want to follow Yii conventions, where module components are still defined in the app config... Why configure plugins via the Plugins service rather than using the standard module configuration conventions? (edit: probably not actually helpful)

Not questioning the merit of this change at all; I can definitely imagine use cases for plugins opening up the container to customization... Just curious about the considerations that led you towards this particular implementation. Cases for overriding plugin components may be relatively rare, but it still seems like this pluginConfigs array could get pretty deep and hairy...

@khalwat
Copy link
Contributor

khalwat commented Apr 28, 2022

Craft CMS just hit the FC stage; isn't this a new feature?

Also agree with @michaelrog 's comments on the structure.

@brandonkelly
Copy link
Member Author

To be clear, craft\services\Plugins::$pluginConfigs has been around since v3.4.0 – not a new thing. This change just makes that property slightly more useful, for plugins that take advantage of it.

Curiously, why not place these overrides in each plugin's config file? (Seems like it might be slightly more tidy to keep container overrides close in code to plugin settings.

The case for configuring a plugin via pluginConfigs vs its settings is kinda similar to things that can be configured via config/app.php vs config/general.php. Some things warrant being proper config settings; others don’t.

Also consider that traditional plugin settings end up in the project config, even if configured via the plugin’s config/<plugin-handle>.php file, which can be awkward/unexpected, particularly for things that need to be defined dynamically based on some PHP logic. Whereas things defined by config/app.php will always be defined at runtime.

Or, if we want to follow Yii conventions, where module components are still defined in the app config... Why configure plugins via the Plugins service rather than using the standard module configuration conventions?

That’s the inspiration for this. Plugins end up getting registered as modules on the app, but they are not configurable via config/app.php as modules directly, since they aren’t registered early enough in the request. So this change provides a bridge. It’s just two levels deeper than a traditional module config would be (components.plugins.pluginConfigs.<plugin-handle> rather than modules.<module-id>.)

@michaelrog
Copy link

Cool — Thanks for explaining; makes sense! 👍🏼

@michaelrog
Copy link

michaelrog commented Apr 28, 2022

Curiously, are yall planning to deprecate the extra.components key in plugins' composer.json files in favor of this definition scheme?

@khalwat
Copy link
Contributor

khalwat commented Apr 28, 2022

Ref: samdark/yii2-cookbook#169

@brandonkelly
Copy link
Member Author

We’ve sortof soft-deprecated it – there’s not been any mention of it in the plugin guide for quite a while – because the disconnect of configuring your PHP module via a JSON file was a little awkward (not to mention annoying/confusing you need to composer update for changes to take effect.) But we don’t have any plans to actually deprecate or remove the functionality

@brandonkelly
Copy link
Member Author

@khalwat I don’t think each individual plugin should have its own proprietary way of making itself configurable.

@khalwat
Copy link
Contributor

khalwat commented Apr 29, 2022

@brandonkelly wasn't suggesting that. Just noting the config format of:

    'params' => [ ... ],
    'components' => [
         // ...
    ],

Feels weird for it to be so deeply nested in:

return [
    'components' => [
        'plugins' => [
            'pluginConfigs' => [
                'my-plugin' => [
                    'components' => [
                        'myComponent' => [
                            'myProperty' => 'foo',
                            // ...
                        ],
                    ],
                ],
            ],
        ],
    ],
];

...but you explained the reasoning, so away we go.

@brandonkelly
Copy link
Member Author

Well it’s the same format; just nested further down, and I didn’t include params in my example (gross).

You could still give each plugin its own config file and require them from config/app.php:

return [
    'components' => [
        'plugins' => [
            'pluginConfigs' => [
                'my-plugin' => require(__DIR__ . '/plugin-configs/my-plugin.php'),
            ],
        ],
    ],
];

(Just don’t put the plugin config files directly in the config/ folder, or Craft will try to use them to configure the plugins’ settings.)

khalwat pushed a commit to nystudio107/craft-instantanalytics that referenced this pull request Sep 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants