Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Blocks make use of categorized plugins. Rules needs exactly the same functionality for actions and conditions and other plugins - so let's make it re-usable.
Proposed resolution
Provide a trait and a respective interface.
Remaining tasks
Do it and make use of it for actions and conditions.
User interface changes
-
API changes
None.
Beta phase evaluation
Issue category | Task: It refactors existing functionality to make it re-usable and applies it to more plugin types, e.g. #2373491: Categorize field type plugins |
---|---|
Issue priority | Major, as it is important to contributed projects (=Rules) for being able to keep supporting d7 features based on d8 core APIs. |
Disruption | The change is not disruptive as it is totally backwards compatible, but
|
Comment | File | Size | Author |
---|---|---|---|
#40 | d8_category.interdiff.txt | 11.39 KB | fago |
#40 | d8_category.patch | 19.75 KB | fago |
#31 | d8_category.interdiff.txt | 3.09 KB | fago |
#31 | d8_category.patch | 19.3 KB | fago |
#25 | interdiff.txt | 823 bytes | amateescu |
Comments
Comment #1
fagofirst patch attached, does not yet implement it for conditions and actions.
Comment #3
fagoImproved the trait a bit and updated the patch to make use of the new trait for conditions and actions also.
Comment #4
fagoAdded the category to annotations.
Comment #7
fagoCompleted the patch, this should be ready now.
Comment #9
fagoouch - BlockManager::getSortedDefinitions() was filtering for definitions without context. We've got test coverage for that, but it's not documented to behave that way. :-/
Let's fix this, such that we can make use of those helpers with passed in $definitions as well. That way you can categorize any set of already filtered definitions, while it just defaults to use all definitions.
Comment #10
fagoattaching interdiff also
Comment #11
XanoWe are now introducing even more code that does not work with object plugin definitions.
Comment #12
fagoYes. I hate the fact that plugin definitions are bound to arrays, but that's the current API so we have to work with that. Also, it's just a default implementation - you do not have to use it.
Comment #13
fagoarray[]|null - yes.
nope, as to HEAD this is an array.
No, it's single valued.
Is that the standard way to do it? I copied the See from an existing trait.
Comment #14
XanoComment #16
XanoComment #17
fagoThanks, changes look good.
Comment #19
klausiThis looks almost ready!
Looks like there is no test coverage for this trait? Or is that already covered with block plugin test cases? Could you add a comment where this is covered?
So the assumption is that only modules can provide plugins? The plugin definition uses "provider" to name the extension providing the plugin - I'm not sure if themes or install profiles even can provide plugins.
Comment #20
Berdir2. More importantly, the comments still talk about block, should be plugin.
A install profile should be in the module list too, and the worst thing that would happen to a module is that it would get the machine name in category if it doesn't specify it manually.
Comment #21
fagoYes, it's mostly covered indirectly with BlockUITest, but this misses coverage for some edge cases. So I've added a unit test case for it.
ad 2, I fixed the block comment to talk about a plugin now. Also, I improved code a bit such that categorized definitions are sorted as well.
Comment #22
klausiThe new test case looks good, thanks! Only minor nitpicks left:
there should not be a a space before and after the | separator.
missing trailing comma.
Inconsistent usage of [] and array() in this test file. Please use one or the other everywhere.
no needs to document @return here. Just use {@inheritdoc} and add the additional comment under it.
Exceeds 80 chars.
why does the test class have to override this method? Please add a comment.
Comment #23
fagoThanks, updated patch to account for all remarks exception for the following:
If you read the code, it should tell you. I'd have added the comment that it processes definition categories, but that the method call already says - so I just left it as it was.
Comment #24
klausiAh, I see.
So this looks good to me now.
Comment #25
amateescu CreditAttribution: amateescu commentedAn object is not casted to a string when used as an array key.
Simple fix attached since I already wrote it when implementing this new trait for field type plugins.
Comment #26
yched CreditAttribution: yched commented$definition['category'] can be an object ? Sounds weird - when does this happen ?
Comment #27
yched CreditAttribution: yched commentedAlso, not convinced by "use module name as fallback when no description is provided".
That's taken from the exiisting code for Blocks, and is possibly fine for the Blocks UI use case, but doesn't feel like the generic behavior we want for all cases ?
Comment #28
amateescu CreditAttribution: amateescu commentedIt's always an object, just like 'label' and 'description' and all the other translatable keys from a plugin annotation, they're instances of
\Drupal\Core\StringTranslation\TranslationWrapper
.That's just a protected helper method, it's not the default, as can be seen in the patch from #2373491: Categorize field type plugins.
Comment #29
Wim Leerss/definitions/plugin definitions/
Wow, never seen this before.
At first: WTF.
Having read the other hunks in this file: makes sense.
Still only supports modules?
{@inheritdoc}
Nitpicky nitpick: missing trailing newline.
Comment #30
yched CreditAttribution: yched commented@a 'fliptable' mateescu : oh, right - thanks, don't mind me :-)
Comment #31
fagoaddressed #29.
ad, 29.3: >Still only supports modules?
Not sure how you mean that, but nope - it works with any kind of categories. The default-default is the module/provider of the plugin, but any plugin manager can use it's own default category.
Comment #32
klausi#29.4: {@inheritfoc} does not fit here because a trait cannot implement an interface, so it does not inherit anything. So the direct reference is fine.
So looks RTBC again.
Comment #33
fagoOps, sry I forgot to mention that - thanks. Yes, inheritdoc is not applicable, so we use those "Implements .." docs instead. The patch just follows what we are already doing for traits elsewhere - no new invention :)
Comment #34
alexpottThis issue is a normal task so we need to outline how it fits within the allowable Drupal 8 beta criteria. Can someone add Drupal 8 beta phase evaluation template to the issue summary.
Comment #35
fagoI've updated the summary with the template. Also, this is important for Rules to be able to keep supporting d7 features based on d8 core APIs, what I think qualifies this to be major.
Comment #36
fagoComment #37
fagoComment #38
fagoApparently there can be troubles if system.module is included as well, thus we need to get #2392281: system.module is included in our PHPUnit tests in first.
Comment #39
dawehnerIt is odd that the BlockManager has to take care of that. A concept of a broken plugin is probably a problem in a lot of places. Do we have an issue to solve just that? (I know its out of scope for this issue)
Isn't that exactly what ModuleHandlerInterface::getName() is supposed to do? ... In case there are modules without a label, we should fix it in there.
Let's not criple in these old documentation lines and use {@inheritdoc} instead.
Maybe this line is worth to have a quick one line documentation.
... Afaik always did not used the intentation, but gladly we don't need it.
Is Impl. as a name a thing?
Comment #40
fagoAgreed, not that I'd know.
Right, except that in our case $module can be any provider. I improved things by renaming this to getProviderName() and to use the module handler for fetching the module name anyway.
See comments #32,#33.
4.,5, 6.: fixed
Comment #41
fagoAlso, stumbled over #2392429: ModuleHandlerInterface::getName() parameter name does not match its documentation while re-rolling this.
Comment #42
tim.plunkettWhy not follow our normal pattern?
Then no need for a comment.
Now we have this twice, once with using a t() call as the array key? :( :( :(
Comment #43
fagoBecause there is no easy way to inject into the trait and make users of the trait aware of that - but the modulehandler property is already set on plugin managers so we can access it that way as documented. That way, the trait will respect the dependency injected module handler of default plugin managers.
-> Imo it makes sense to comment that, plus we need to use isset() or it will notice if the trait-ed objected does not have the property.
Now we have this twice, once with using a t() call as the array key? :( :( :(
>Now we have this twice, once with using a t() call as the array key? :( :( :(
Well, the translated key is just how optgroups work - they have the label as key - nothing we can do about that. Having the unset twice is unfortunate - yes, but the whole broken thing of filtering it out for some UI-used methods but not in some UI-unused methods is a pre-existing ugly thing of blockmanager - that's not changed here.
Comment #44
dawehnerCan we just fix that quickly?
Comment #45
dawehnerI'm stupid.
Comment #46
alexpottUnblocking contrib is prioritised for beta and having less duplicate code reduces fragility. Committed d3e3d70 and pushed to 8.0.x. Thanks!
Thanks for adding the beta evaluation for to the issue summary.