October: Add a list of optionally required plugins in Plugin.php

Created on 21 Dec 2019  路  31Comments  路  Source: octobercms/october

Hello!

I'm Marketplace plugins author and I'm facing the following dilemma: I need a possibility to require only one of two plugins.

I got Vdomah.Roles which works either with Lovata.Buddies or RainLab.User. But the problem is that Marketplace doesn't support optional required plugin. So you can either require both Lovata.Buddies and RinLab.User, or not require any plugin at all. In first case you force user to have redundant plugin in his project. In second case your plugin doesn't cause installation of it's dependencies - user will need to install Buddies or User manually. Also in the second case your plugin will not be displayed on the Buddies or User marketplace page that is bad for it's recognition and popularity.

In Vdomah.Roles plugin I've chosen the second case. And my plugin looses in popularity.

Today a new support ticket was created in my other plugin, that extends RainLab.User https://octobercms.com/plugin/support/vdomah-jwtauth/use-different-user-plugin. User planetadeleste asked me if I can update my plugin to be able to work with Lovata.Buddies. But I don't wan't my plugin Vdomah.JWTauth to disappear from RainLab.User page on Marketplace like Vdomah.Roles did. So I got the only option to create new plugin with the same functionality to integrate with Lovata.Buddies.

This comment from another issue here suggest the same idea, so I see that this topic is quite desired by programmers of OctoberCMS:
https://github.com/octobercms/october/issues/4307#issuecomment-537494111

For my particular case it would be great to have the option like this:
public $required_one = ['Lovata.Buddies', 'RainLab.User'];
But it also can look like a list of optional plugins. With the only purpose to show the dependent plugin (like my plugins Roles or JWTAuth) on the pages of all optional required plugins. And to not force installing any of this plugins during the dependent plugin installation:
public $required_optional = ['Lovata.Buddies', 'RainLab.User'];

Review Needed Conceptual Enhancement

Most helpful comment

@bennothommo that sounds good to me, although I'm not sure about renaming it. Yes, dependencies would be more accurate, but on the other hand require isn't that inaccurate, especially with "soft" requirements (i.e. optional dependencies) being indicated with a separate syntax @. If we renamed it we'd have to support both $require and $dependencies so I would prefer it was left as $require.

Does anyone want to take a stab at mocking up the UX that would handle all three dependency types in the following situations:

  • Installing a plugin from the command line
  • Installing a plugin from the plugin management screen
  • Warning the user about missing dependencies in the dashboard and plugin management screens

All 31 comments

Happy to explore this. In this case, you could make your plugin compatible with the following scenarios:

  • Neither Lovata.Buddies or RainLab.User are installed (prompt the user to choose, guide them on the differences)
  • Only Lovata.Buddies installed
  • Only RainLab.User installed

If your plugin can function with either, then it in theory it should function with neither

If your plugin can function with either, then it in theory it should function with neither

Yes, that's the way my plugin Vdomah.Roles works now. To be precise, it doesn't function at all if neither of two auth plugins are present in the project. It just exists there and doesn't brake anything waiting for user to install any of two auth plugin.

It would be useful and for themes too https://github.com/octobercms/october/issues/4307

I had the same need in a plugin I created recently. Plugin required one of Lovata.Shopaholic or OFFLINE.Mall, but could not require one or the other without requiring both.

In my opinion, this is a frequent case when one plugin supports optionally different plugins similar in logic.

For a special case, I think it鈥檚 possible to use something like this in the Register or Boot Plugin method:

if(PluginManager::instance()->hasPlugin('Lovata.Buddies')) {
            $this->require[] = 'Lovata.Buddies';
        } else {
            $this->require[] = 'Rainlab.User';
        }

Judging by the logic of loading dependencies and checking them, it should work.

@LeMaX10 unfortunately that wouldn't work. Requirement processing happens before the boot method of a plugin runs.

unfortunately that wouldn't work. Requirement processing happens before the boot method of a plugin runs.

Oh yeah. You're right.
This would be possible when trying to override this in the constructor, however, requesting the installed plugin through the constructor will fail, except to refer to its file version :(.

The best and easy way for plugin developers, was to has something like

$require = ['Lovata.Buddies|RainLab.User']

Additionally could have $require = ['@Author.Plugin']; for optional dependencies

@LukeTowers but if is optional, doesn't make sense to be in $require, don't you?

A $suggest property, similar to composer's suggests mechanism would be great for optional dependencies.

I think a combination of @alvaro-canepa's idea of the pipe symbol to denote a chain of plugins in which one of them must be fulfilled, and @LukeTowers suggestion of an @ symbol to denote an optional dependency might provide the most flexibility. The term $require should then be renamed to $dependencies to not imply that everything is required.

For example:

public $dependencies = [
    'RainLab.Blog', // Blog plugin MUST be installed
    'RainLab.User|Lovata.Buddies', // Either the User plugin OR the Buddies plugin MUST be installed
    '@OFFLINE.SiteSearch', // SiteSearch plguin MAY or MAY NOT be installed
];

When processing / downloading dependent plugins for a particular parent plugin, you would follow the steps in @daftspunk's comment, prompting the user to select one of the chained plugins if neither of them are available. For all intents and purposes, the optional ones can be ignored as they aren't required for the plugin to function.

@bennothommo That would be great. Maybe the @LukeTowers idea can be for suggested plugins, like do composer.

@bennothommo that sounds good to me, although I'm not sure about renaming it. Yes, dependencies would be more accurate, but on the other hand require isn't that inaccurate, especially with "soft" requirements (i.e. optional dependencies) being indicated with a separate syntax @. If we renamed it we'd have to support both $require and $dependencies so I would prefer it was left as $require.

Does anyone want to take a stab at mocking up the UX that would handle all three dependency types in the following situations:

  • Installing a plugin from the command line
  • Installing a plugin from the plugin management screen
  • Warning the user about missing dependencies in the dashboard and plugin management screens

This issue will be closed and archived in 3 days, as there has been no activity in the last 30 days.

  • If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue. - If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

This issue will be closed and archived in 3 days, as there has been no activity in the last 30 days.

  • If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue. - If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

Up!

This issue will be closed and archived in 3 days, as there has been no activity in the last 30 days.
If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue.
If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

This issue will be closed and archived in 3 days, as there has been no activity in the last 30 days.
If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue.
If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

Up 馃槑

Friendly reminder about the premium support program @lautsevich 馃槈

Trying to mimic the behavior of this feature with my Vdomah.Roles plugin.

The goal is to make two adapter plugins for RainLab.User and Lovata.Buddies. Yesterday I've submitted Vdomah.RolesBuddies plugin. Which do two things: requires Lovata.Buddies and Vdomah.Roles and adds role_id column.

But my plugin was rejected because of guidelines violation.

If a plugin extends tables belonging to other plugins (like lovata_buddies_users), the new columns must have a prefix

So column should be named vdomah_rolesbuddies_role_id. But in the same time Vdomah.Roles plugin can be used without Vdomah.RolesBuddies. So role_id column should be named vdomah_roles_role_id. So role id column should be named same for my two plugins: Vdomah.Roles and Vdomah.RolesBuddies.

I understand that this violates guidelines but I'm forced to do it this way because inability to optionally require plugin. So I hope for understanding and that you allow me to name column as vdomah_roles_role_id but to add this column to lovata_buddies_users from Vdomah.RolesBuddies migration. Because this plugin is just adapter for Vdomah.Roles to compensate inability of optional require.

@vdomah the simple solution is to just prefix it with your author name: vdomah_role_id. This should fulfill the requirement from the guidelines, AFAIK nothing says it has to be author_plugin_column, it just has to be prefixed to prevent conflicts with other plugins. In some cases requiring the full author_plugin_ prefix wouldn't even work within some DB column length restrictions.

@LukeTowers thanks, that simplifies things enough.

@vdomah why not duplicate jwtauth to support only Lovata.Buddies.

@alvaro-canepa I鈥檒l try this approach with jwtauth, may be moving businesses logic code to shared package to require by composer

This issue will be closed and archived in 3 days, as there has been no activity in the last 60 days.
If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue.
If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

This issue will be closed and archived in 3 days, as there has been no activity in the last 60 days.
If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue.
If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

This issue will be closed and archived in 3 days, as there has been no activity in the last 60 days.
If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue.
If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

Hi, is it really done? Just can't see the corresponding commit.

@vdomah it's not done, it was automatically archived as @github-actions stated above.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oppin picture oppin  路  3Comments

mittultechnobrave picture mittultechnobrave  路  3Comments

EbashuOnHolidays picture EbashuOnHolidays  路  3Comments

dunets picture dunets  路  3Comments

mittultechnobrave picture mittultechnobrave  路  3Comments