Currently it is possible to alter the plugin definitions via alter hook(specific to the plugin id) but the result is cached and so if one needs to remove certain plugin it is "all in" approach.

I have encountered multiple scenarios where I want to make a certain plugin unavailable based on some conditions but not globally. At this point this is not possible because the definitions are cached and the alter hook runs before the definitions are stored in cache.

I propose addition of new alter hook that would run after the cached information of plugin definitions is gathered and returned so that the developer could easily implement on/off switch for any plugin dynamically and prevent it from loading.

Comments

Anonymous’s picture

ivanjaros created an issue. See original summary.

EclipseGc’s picture

Status: Active » Closed (works as designed)

Just call to the getDefinitions() method of your plugin manager and then add a custom alter for your scenario in YOUR code. There shouldn't need to be one of these for run time. Filtering available plugins is a separate problem from finding the available plugins, and you're kind of conflating the two ideas here.

Eclipse

Anonymous’s picture

Status: Closed (works as designed) » Active

I don't want this only on MY plugins and overriding plugin manager for plugins I want to alter is retarded.
Beside DX, imagine a UI/form where you have a list of plugins of certain type(for which you need their definitions) and you can enable/disable each one of them via simple checkbox. Not all plugins are configurable and provide config entity for their configuration so this would make something like this possible.

EclipseGc’s picture

Status: Active » Closed (works as designed)

I didn't say you needed to override the managers, I said your UI should be responsible for the filtering.

Anonymous’s picture

Status: Closed (works as designed) » Active

The UI is just an example. So please explain to me how is this possible now without overriding plugin managers?

EclipseGc’s picture

Status: Active » Closed (works as designed)

$definitions = $manager->getDefinitions();
$definitions = $this->filterDefinitionsOnSomeCriteria($definitions);
return $definitions;

You can call to the manager yourself, you can override UIs that core or contrib provides, you can filter these definitions HOWEVER you like. You can alter (through existing methods) the $definitions array itself and append criteria of your own choosing to filter on later, you can do a GREAT many things to customize how a specific manager's plugins are treated. I don't see any need for a runtime alter at some generic level of the system. If you wanted to add a runtime alter to your specific use case, any of the above-mentioned approaches are likely to be helpful in that regard.

Eclipse

Anonymous’s picture

Status: Closed (works as designed) » Active

What you're describing is essentially impossible in real life for plugins defined by other modules and even for own plugins this would be too much work to put in place(for a SINGLE plugin).

EclipseGc’s picture

Instead of telling me how impossible this is, why don't you give the example you're dealing with? That's likely a way more constructive use of our time.

Eclipse

neclimdul’s picture

I'm a bit confused by this issue and the tone does make it a bit hard to follow as well.

That said, if I understand the requirement described in #3, you're talking about building a UI where you could see a list of all plugins for the type, then you could turn them on and off with checkboxes. Then every where else, whenever the plugins are listed or used, the disabled plugins would not show as if they don't exist.

I think the hardest thing described about the process in #3 doesn't really have anything to do with caching. Just clear the cache for that particular plugin definition when you submit the form and you're done, plugins don't show up. The hard part would be building a path around your filtering so you get the unfiltered list on the management form.

So setting aside that example and addressing the concept, by definition of how caching works, the reason you'd want to filter(or expand) the list outside of the cached values would be because your filter doesn't align with the cache context. For example if you filtered per user but the cache was site wide or if you wanted to filter per page but the cache was per user. Is that what you're asking for and could you help us understand how that would be useful?

EclipseGc’s picture

Yeah, I intend on doing exactly that with blocks for panelizer integration eventually, and it just means that I'll be storing a separate config object that my UI will do an array_intersect on before displaying plugins. That won't make it disappear for core, but if I wanted it to, I could hijack core's block placement UI and make it respect the same config object(s). I'm still not sure I see a problem here.

Eclipse

Anonymous’s picture

I started to write an example(with colors :D) but I see that my description might be misleading. Discard the UI, that was just an use case I have. The important thing is this: being able to get ALL unaltered plugin definitions so that I know 100% which plugins do really exist. And second case where I can "hide"/disable some plugins so that they just appear non-existing and therefore unusable. Also the alter hook is not a good idea as I thought more about this. Something like getDefinitions() and getUnalteredDefinitions() makes more sense.

Imagine having a node with custom field and this field has select widget that lists plugins of some type and you want to hide one of those plugins. How would you do that now? You would have to remove the plugin's definition with the plugin alter hook. But that way you have no way of knowing this plugin exists somewhere else in the code. So currently it's all in or all out, there is nothing in the middle that would allow you to hide plugin but still being aware of its existence.

My use case is that I want to have a listing of my plugins and I want to enable/disable any of them so they cannot be used BUT I still need to list them in this listing if they are disabled(so I can enable them again), which means removing their definitions with the alter hook is not possible since they would disappear for good.

EclipseGc’s picture

So it sounds like you're a bit of two minds about what you need, I'll try to illustrate the approach I'd take, and maybe you can extrapolate out something that will work for you.

Field on an entity:
If you have a custom field type that shows a list of plugins and allows plugins to be turned on or off for use at say... run time of that entity being rendered, I could see you wanting to limit the list from one field configuration to the next. As you might have already guessed, I'd be saving the available plugin information into the config entity that represents the field config, which the field will get during edit and render time which will allow you to display plugins configured to be available vs all plugins. This would also allow you to store which plugins the content author wanted to have run in the field's storage, so I think we covered all the bases.

Do you have a custom plugin type for what you're doing? or is this for some pre-existing plugin type? I ask because there are plugin managers that do filter the list of available plugin definitions, but it's by some knowable set of criteria and it's a filter (not an alteration of the cache). Check out \Drupal\Core\Plugin\Context\ContextAwarePluginManagerTrait which is used by both the BlockManager and the ConditionManager (since those are context aware plugin managers). This might give you some additional ideas for more how to affect your available plugin lists.

Eclipse

Anonymous’s picture

Basically what I need, and it is not specific to any plugin but in general to all plugins, is to be able to "hide" a plugin(not plugin type, only plugin "instance") so it cannot be used but still know that it exists(I can get its definition). Again, it is not plugin-specific. It would be easy with plugins that have config entities where I could just alter the entity query, but that can be used only on some plugins + I would be actually working with config entities and not the plugins themselves.

Another two examples that can shine some light on this:

Example A(N=1):
You have a website that your client uses and you provide currency conversion. You define a "Currency" plugin type where each currency is a single plugin(US Dollar, Euro, Yen...). Each currency costs 5$ for the customer bot be able to use that you charge him monthly. So if the customer will ENABLE a currency, he'll have to pay you for the usage. He/you can easily turn on/off currencies based on the client's needs without having to create 100+ modules, one per currency(ie. each module would provide one currency plugin).
a) you do not want to give the user access to manage modules and
b) it just doesn't make any sense do do it this way.

Example B(N+1):
You have a community site where people can play some sort of games and trade items. These items would be plugins of "GameItem" plugin type. Based on credits or any arbitrary conditions you would take or give permissions to certain user(s) to use certain items. So now you are not dealing with a single user/customer but with N+1... And using modules to provide the items in this case would be literally impossible.

EclipseGc’s picture

Status: Active » Closed (works as designed)

So, since you yourself seem to have come to the conclusion that an alter is not going to solve your problem, I'm closing this. All I can tell you is that it's pretty easy to build filters of the available plugins. It might just mean you have to take over some controllers or something along those lines.

Eclipse

Anonymous’s picture

I know it is possible, but it is very hard and time consuming to override all plugin managers. That's why this is a Feature request and not a support request.