Problem/Motivation
Currently, the set of properties for a particular plugin type is only defined in one place - previously the plugin type's annotation class, and now the plugin type's attribute class.
This leads to some problems, such as:
- The long-standing problem where the EntityType annotation/attribute defines a 'field_ui_base_route' which is actually for field_ui, an optional module
- The long-standing feature needed for Views, where we'd like to add a property to FieldType plugins for Views, which is, again, an optional module -- #2337515: Allow @FieldType to customize views data
Proposed resolution
We don't know yet, but three options present themselves, each implemented in a separate PoC MR in this issue's fork:
- Door #1: Create an API that would allow modules to define supplemental attributes that could be applied to plugin classes. The main obstacle here is that it won't play nicely with the file-based plugin attribute discovery cache. One way around that would be (per @catch in #3009349-70: Revert migrate_drupal source annotations to attributes conversion) to prefix file cache keys with the names of all currently installed modules. This may be the least complex implementation path, but might also have knock-on effects in terms of storing many additional cache data variations in APCu and the database. Implemented in !7793.
- Door #2: Core could provide an attribute that would be used to set supplemental plugin properties. That attribute class could be extended by core, or contrib, to account for specialized plugin definitions (such as
EntityTypeInterface). Implemented in !10218. - new Door #2AAdapting implementation details from #2 to implement #1. Basically, use the
MissingClassDetectionClassLoaderto detect when attribute classes are not available during plugin discovery. Store the property attribute data in the file cache, then add the property data from the attributes when the classes are available. Implemented in !13976 - Door #2: Just allow arbitrary additional properties to be set on the plugin definition itself. The drawback here is that every plugin type attribute which wanted to support this, would need to have its constructor updated, so this would be a fairly large-scale, if straightforward, change to core. Partially implemented -- enough to give you a sense of what the change would look like -- in !10668.
Remaining tasks
- Choose an approach, and file any blocking issues.
- Add change record
- Commit any blockers, and ensure the chosen approach is implemented with test coverage.
- Commit the change and party!
User interface changes
None anticipated.
API changes
- Plugin classes can use
PluginPropertyattributes to add supplemental properties to their array-based definitions - Modules can extend
PluginPropertyto set a specific property or properties on specific plugin type(s). These properties are set on the definition only when the module providing the property attribute class is installed - Basic use cases are provided:
AllowInNavigationattribute to apply to Block plugins,FieldUiBaseRouteattribute to apply to entity type definitions
Data model changes
None anticipated.
Release notes snippet
TBD
| Comment | File | Size | Author |
|---|---|---|---|
| #63 | Drupal_Canvas.png | 32.51 KB | mherchel |
| #48 | 3443882-nr-bot.txt | 91 bytes | needs-review-queue-bot |
| #46 | 3443882-nr-bot.txt | 91 bytes | needs-review-queue-bot |
| #15 | 3443882-nr-bot.txt | 90 bytes | needs-review-queue-bot |
| #10 | 3443882-nr-bot.txt | 3.13 KB | needs-review-queue-bot |
Issue fork drupal-3443882
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
joachim commentedPushed the work I did on #3396166: Convert entity type discovery to PHP attributes to a MR.
Still to do:
- > unless there is a deprecation marked.
Bikeshedding: what do we call these?
- I initially went for 'extending plugin attributes' but I think that's misleading because there is no class inheritance going on
- '3rd party' doesn't apply, I feel, because with config 3rd party settings, those properties are completely controlled by another module - they are set, and read. Here, the properties are set by modules that implement plugins, and read by the module providing the extra attribute
- additional plugin attribute?
- supplemental plugin attribute?
Comment #4
mstrelan commentedMaybe not extending the plugin attribute, but you are extending the plugin. So maybe just rearranging the words to "plugin extension attributes" or something to that effect.
Comment #5
larowlanHow about `Non-discovery attributes` ?
Comment #6
kristiaanvandeneyndeI'd go with Third-Party for two reasons:
Comment #7
joachim commentedThanks for the suggestions!
I've added functionality for allowing 3rd-party (let's go with that!) attributes to override a main attribute property, if that property is marked as deprecated.
This is the mechanism that will allow us to move properties like field_ui_base_route from the main attribute into a 3rd-party attribute.
Comment #8
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #9
joachim commentedComment #10
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #11
joachim commentedComment #12
smustgrave commentedAll tests appear to be failing
Comment #13
joachim commentedYes but I'd like a review of the approach before I write tests.
Comment #14
smustgrave commentedMaybe can help/
Comment #15
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #16
plopescThis issue would make a difference and other modules like Navigation or Dashboard could take advantage of this new feature. Just one question about a possible scenario that I'm not sure whether current implementation would cover.
* Navigation adds a new 3rd party attribute for Block Attribute
* Module X provides multiple feature, one of them is a Navigation block, defining the corresponding Navigation specific block attribute
allow_in_navigation* For any reason, Navigation module is not enabled in the site
* Should the
Error: Unknown named parameter $allow_in_navigation in ReflectionAttribute->newInstance()...be triggered?How this scenario should be handled?
Comment #17
joachim commented@plopesc I don't think that would happen:
- Navigation module provides an attribute class NavigationBlock.
- MyModule adds a NavigationBlock attribute to its block plugins, in addition to core's Block attribute
- If MyModule is enabled but Navigation is not, the NavigationBlock attribute is simply ignored.
Comment #18
berdirNot sure if that could be a handled in the same issue, but I think that specifically the entity type attribute could really benefit from splitting up the attribute class, to make it more similar to how Doctrine and also for example Drush command attributes:
Right now, it looks like this:
We'd split up specifically repeatable but also optional and also but not only third party keys into separate attributes. Haven't really thought about how to merge it together again, since the result still needs to be a single definition.
#[ContentEntityType(
id: 'node',
label: new TranslatableMarkup('Content'),
...
)]
#[Handler('storage', NodeStorage::class)]
// Or maybe even more specific subclasses for common handlers
#[StorageHandler(NodeStorage::class)]
#[Link('canonical', '/node/{node}']
?>
I think that would be a lot closer to how other PHP frameworks deal with this and while it probably be just as long, it would be less complex and easier to format. Pretty sure that our entity type attribute class is going to give any developer familar with Doctrine a heart attack ;)
Comment #19
kristiaanvandeneyndeBig +1 to #18. The hard part with splitting them up will be to figure out which attributes need to be aggregated into the entity type info and which are completely unrelated. It's not unthinkable people would add non-entity type attributes there for whatever reason.
I also plan to one day suggest we turn entity type handlers into services like I did in Group and having these separate attributes would go a long way to keep the declaration validation logic in one place. But that's for a more distant future as the current handler interfaces tend to be quite big.
Comment #20
joachim commentedI think #18 would need a different issue. It's not just the changes to how we assemble data in the discovery class, but also we need a new way for the plugin type manager to say that there are multiple 'official' attributes. And then there'll be tons of bikeshed about how to slice up the entity type attribute...
Comment #21
kristiaanvandeneyndeOh yeah, definitely a separate issue. But it could be a good idea to explore that avenue first and then return to this issue with its findings and/or commits.
Comment #22
joachim commentedThis issue is a contrib blocker though, now I think of it.
Suppose you have a contrib module which invents the 'floopiness' property on core's Block plugins.
If you want to add that to existing plugins, nothing changes -- you use the alter hook.
But if you provided a Block plugin, up until now you could do this in an annotation
With attributes, that will crash, and your module needs to implement the alter hook for its own plugins.
Comment #23
berdir> With attributes, that will crash, and your module needs to implement the alter hook for its own plugins.
Which means it's not a blocker, just an inconvenience.
The thing with the third party discovery added here is is that it assumes that the plugin definition is a array-dumping-ground. object based plugin definitions need to explicitly support additional properties too, which entity types actually do, also on the attribute. They have an explicit additional array property where extra stuff can be put into, there are IIRC also a few test entity types that make use of that.
Any plugin type that wants to make it easier to support additional stuff can add that property as well.
Agree that #18 is kind of a different scope, but maybe this issue is just a more specific use case of that, and we if support additional attributes as a concept, based on a common base class/interface and have a mechanism that allows for them to control how the result is merged, then it doesn't really matter if the extra bits are official or not.
And of course, the ability to have that and implementing it for entity types would not be the same issue either, we could have a proof of concept for our test plugin types, just like this issue currently also does.
Comment #24
joachim commented> The thing with the third party discovery added here is is that it assumes that the plugin definition is a array-dumping-ground.
Yup. I considered having values from 3rd party attributes go into something like a $definition['third-party'][$attribute_provider] array, but I wasn't sure whether that was over-complicating.
Do you think that would be cleaner?
Comment #26
godotislateI think it's worth investigating how much overlap there is in a use case like splitting up the entity type attributes and the use case of having other modules provide supplemental attributes.
A few thoughts:
::get()called on a Plugin attribute does not necessarily return an array; it can also return an object. SeeCKEditor5Pluginfor an example. In which case, we can't assume that the$contentvariable inAttributeClassDiscovery::parseClass()is an array that new properties can just be appended to. I think we can solve this with a method on the base option/extender class likeaddToDefinition(array|object &$definition). The base method can be gated to only work an array definition, leaving child classes that work with plugin attributes that return objects to override that on their ownI'm pushing a PoC MR here that hopefully demonstrates what I'm talking about a little better.
One additional concern that is not yet accounted for:
Plugin definitions discovery is backed the FileCache stored in APCu. The FileCache is only invalidated by plugin class file modified time, so Drupal cache clears do not affect its contents. That means that installing or uninstalling a module will not invalidate the FileCache. In the example of Field UI, if entity type definitions are discovered with Field UI uninstalled, then that entity type definition is stored in FileCache without the field UI base route. Even after installing Field UI, FileCache data is not invalidated, so the field UI base route is not added to the entity type definition.
I'm not sure how to get around this without needing to invalidate the FileCache on every module install. This is also a very difficult thing to capture in automated tests, because all classes are autoloaded during tests regardless of whether their modules are installed.
Comment #28
godotislateDraft MR 10179 opened per #26. I think the Nightwatch test failure has to do with field UI as mentioned, but I haven't confirmed.
I used attribute classes for Handler/StorageHandler/FormHandler for entity types, but I forgot that those plugin definitions aren't arrays, so they aren't a good example for how the base class works with array definitions, but I think it still shows how the attributes would work overall.
ETA. Actually, I think PoC does suggest that splitting up the entity type attribute into multiple attributes might be better as a separate issue, especially since all the entity type attributes would live in core, so there wouldn't be any worry about stale caches during discovery.
Comment #29
godotislateGave it some thought, and refactored my PoC MR 10179.
My new approach to deal with the file cache: It won't be allowed to use attribute classes from modules. Only the base extender attribute (which I've bikeshedded myself again to be name PluginProperty) and some subclasses that all live in \Drupal\Core can modify plugin definitions. In order to annotate a plugin with PluginProperty attributes that such apply only when a module is installed, the
providerproperty of the PluginProperty attribute must be set to name of the module dependency.Attribute class discovery is changed so that the definitions parsed from Plugin attributes and altered by core provider PluginProperty attributes are saved in the file cache. PluginProperty attributes that have a provider other than core are saved in the "third_party_properties" in the array returned by parseClass and saved to file cache. The third party attributes are applied after retrieval from file cache if their module provider is installed.
I included examples of PluginProperty subclasses and applied them to Node, which looks like this:
MR is still a PoC, so there's some clean up, documentation, and more tests to be included.
Comment #30
joachim commented> (which I've bikeshedded myself again to be name PluginProperty
What about ThirdPartyProperties, to match how the config system calls this concept?
> In order to annotate a plugin with PluginProperty attributes that such apply only when a module is installed, the provider property of the PluginProperty attribute must be set to name of the module dependency.
That makes sense.
It's a shame though, as the huge benefit of attributes is that you get IDE support for property names and types.
Thinking about it, this filecache problem is not just a Drupal problem, it's a PHP problem.
Consider we have package A, which has annotated classes, and it has a class Foo with an annotation for package B which is not a dependency. When the project owner installed package B, the annotation on class Foo is not picked up. Same problem as with modules, just with Composer packages instead. Is it something that's known about upstream?
Comment #34
godotislateI've closed PoC MR 10179. Taking learnings from that MR and reducing scope to remove most of the entity type definition subclasses, I've opened MR 10218. I created a follow up for the entity type property attributes: #3488054: Make it possible to define entity types with multiple smaller attributes
I also removed checking whether existing properties can be overridden. If there is a use case for making sure properties aren't overridden, that functionality can be reinstated, but it complicates logic when setting values with nested keys.
I've also added additional tests and updated the IS. I believe this is ready for review.
Comment #36
godotislateComment #37
godotislateMade a revision to the MR. Instead of using
provider, addedmoduleDependenciesto thePluginPropertyclass, so that multiple modules can be set as requirements for the property to be added to the plugin definition.Comment #38
larowlanComment #39
larowlanComment #40
joachim commented> The FileCache is only invalidated by plugin class file modified time, so Drupal cache clears do not affect its contents. That means that installing or uninstalling a module will not invalidate the FileCache.
We've seen at #3492523: Class "Doctrine\Deprecations\Deprecation" not found that any package update could require a clearing of the file cache.
If we were to update our requirements to say that the filecache needs to be cleared whenever modules or packages are updated, it would give us more flexibility here.
Comment #41
godotislateRebased and refactored a little bit so that stuff that has to do with "providers" or modules is moved to the core AttributeClassDiscovery class instead of component.
There will be a merge conflict with #3490322: Use nickic/php-parser for attribute-based plugin discovery to avoid errors depending on which gets in first. Ideally #3490322 goes in first, but it is not a hard blocker.
Either way, it will be good to get both in to help with #3421014: Convert MigrateSource plugin discovery to attributes and finally finish off moving core plugin types to attributes.
Comment #42
godotislateDiscussed this issue with one of the plugin subsystem maintainers over Slack. He is not completely against having supplemental attributes, but he thinks it might be addressed more easily by allowing arbitrary properties to be set on Plugin attributes:
$this->additional[$key] = $value. (Splitting the EntityType attributes into separate attributes is still valid and would not be tied to this.)I know Drupal core does have a version of this with one plugin type: \Drupal\Core\Layout\Attribute\Layout, which looks like this:
We could possibly add
$additionaltoDrupal\Component\Plugin\Attribute\Plugin, and merge the contents of$this->additionalto AttributeBase::get() in Plugin::get(). This would involved updating all the plugin type attribute constructors as well.Comment #43
joachim commentedI think I had a similar discussion with the same maintainer :)
I'm really not keen on putting things in an $this->additional array. We lose all the benefit of attributes if we do that -- better documentation, better picking up of mistakes, IDE completion, etc.
Comment #45
godotislateI put up MR 10668 with a POC of having a variadic property in the plugin attribute constructor. The EntityType attribute already has an readonly
additionalproperty that's used differently, so I couldn't useadditionalas the property name in the basePluginattribute, and for now it's just$other. Also updated the Block attribute and added theallow_in_navigationproperty to the appropriate navigation block plugin classes per #3443833: Provide a way for other modules to flag block plugin implementations as 'navigation safe' to demo this.This approach works as far as I can tell, but I have reservations: setting arbitrary properties in the attribute is not self-documenting, so it's not immediately obvious where these properties come from or how they're used. Also, there would need to be some effort to update all the attribute constructors, and account for attributes that return objects instead of arrays from
get().Since there's still desire to allow the EntityType attribute to be split up into multiple attributes, discovery will need to be updated to handle multiple attributes. Whether those additional attributes are used to set defined properties, in the EntityType case, or additional properties needed by other modules, such as in the Navigation case, do not seem to be a significantly different implementations.
Comment #46
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #47
godotislateRe-based https://git.drupalcode.org/project/drupal/-/merge_requests/10668
Comment #48
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #50
benjifisherI rebased the feature branch for MR 10668, and there were no conflicts.
It is surprising how simple the change is (+33/-15) given the complexity of the discussion here. I guess this simple approach is just creating a "dumping ground" instead of a way to add first-class attributes to an annotation class. I am still working on understanding the discussion here, so maybe I do not have it quite right.
Comment #51
godotislateSummary of discussion/issue so far:
@catch has suggested in #3009349: Revert migrate_drupal source annotations to attributes conversion #70 that the file cache issue could be addressed by making the file cache entry keys include the install modules list. Doing so would make the original idea possible.
I also just thought of another possibility to make the original possible once #3502913: Add a fallback classloader that can handle missing traits for attribute discovery gets in, but I'd need to POC it first.
Comment #52
joachim commentedTagging as NISU, as only option 2 is currently outlined in the IS.
I think that if #3009349: Revert migrate_drupal source annotations to attributes conversion makes the original proposal possible, we should wait for that, as that has the best DX IMO.
Comment #53
larowlanMarking needs work for an issue summary update, the excellent summary from @godotislate at #51 would be the best starting point for that.
Comment #54
larowlanComment #55
phenaproximaUpdated the issue summary to describe the three approaches.
Comment #56
phenaproximaComment #57
godotislateThanks to @phenaproxima for updating the IS!
@phenaproxima also mentioned this is a Canvas blocker, and he and @catch seemed to have expressed preference on Slack for option 3, which was also the suggestion by one of the plugin subsystem maintainers, maybe it's worth continuing on the POC work in MR 10668. Also, maybe it's fine to do only the Block attribute here, add tests for a "generic" plugin attribute, then add follow up issues to update other core plugin attribute constructors as needed?
Comment #58
phenaproximaTo me, #3 is the most straightforward option. If we mess with the file cache, we're inviting ourselves to enter a world of pain. I also think the third option is the most "obvious" one, and therefore best for DX. I also like that it allows different plugin types to decide if they want to support additional properties or not.
I bet we could reduce implementation pain if we added a trait for plugin attributes that support additional properties. To make it even easier, we could use that trait in
\Drupal\Component\Plugin\Attribute\Pluginso that most plugin types across core and contrib get the capability by default.Comment #59
joachim commented> If we mess with the file cache, we're inviting ourselves to enter a world of pain.
The file cache issue is something PHP is going to have to solve at some point -- the appearance of a new package which gives meaning to a hitherto dormant attribute is a problem that all composed PHP applications will have.
> I also think the third option is the most "obvious" one, and therefore best for DX.
I think it's got the worst DX!
> I also like that it allows different plugin types to decide if they want to support additional properties or not.
The lack of consistency is also bad DX.
Comment #60
phenaproximaFair! I know what I personally would like the most, but I have no particular dog in this fight as long as it gets done somehow.
Makes sense. Why not just add this capability to
Pluginthen, and all plugin types get it by default?Comment #61
godotislateThe changes to the Plugin base class in the MR basically do everything a trait could do. The problem is that, in order to get all plugin attributes to support being passed in arbitrary values, the constructor of each attribute class needs to be updated to capture the additional arguments in to the class property. By rough count, there are 50-60 plugin attribute classes that would need updating, though some are test classes, and some specific attribute classes already allow arbitrary properties to be set in different ways.
Comment #62
godotislatePossibly another reason in favor of allowing arbitrary parameters in plugin attribute constructors (sparked by #3524377-50: Allow to skip OOP hooks and services for modules that are not installed): since we use named parameters, this makes adding parameters in the future more difficult for BC, because a contrib plugin trying to support multiple versions will hit a fatal error passing a named parameter that does not exist in the older version.
Allowing arbitrary named parameters now might make adding any defined parameter later a bit easier, since contrib/custom modules would only need to reorder the parameter list.
Comment #63
mherchelPer @penyaskito in https://drupal.slack.com/archives/C072JMEPUS1/p1762261704549799?thread_t...

Comment #69
godotislateOK, I think I found a way to let modules implement their own attributes that add properties to a plugin definition. This is somewhat based on the work from !10218, which added a PluginProperty attribute class, but extending the class in other modules was not allowed, in order to avoid issues with the file cache.
I've addressed the issue with the file cache by changing
MissingClassDetectionClassLoaderto collect all the missing classes that it comes across when parsing every plugin class during discovery. The idea is that if there are missing classes/traits/interfaces that do not cause an error or exception, then likely the missing classes are attribute classes, because PHP ignores missing attribute class definitions and treats them like comments. All the property attributes, both existing and missing, are saved for each cache item associated with the plugin class file path. When definitions are retrieved from the file cache, the property attributes are iterated through, and the ones that are available add their property values to the plugin definition.To provide sample use cases, an
AllowInNavigationattribute class is implemented and used on navigation module block plugin classes, so that those blocks are available to be placed in the navigation side bar. Also, aFieldUiBaseRouteattribute is implemented in thefield_uimodule and added to the Node entity type definition, so that thefield_ui_base_routeproperty is added to the Node entity type definition only when field_ui is installed. Conceivably,field_ui_base_routecould be deprecated and removed as an argument from theContentEntityTypeattribute constructor in a follow up issue.The base
PluginPropertyattribute only works with array plugin definitions, and it will be left to follow ups to provide attributes that work with plugin types that have non-array definitions. For example, a generic EntityTypeProperty attribute could be implemented in #3488054: Make it possible to define entity types with multiple smaller attributes.The implementation might be a little complex, so I'm leaving creating a CR for later if there's agreement that this is a good way to go.
New MR is !13976.
Comment #70
joachim commentedWould the file cache problem be resolved now because of the new DrupalInstalled::VERSIONS_HASH that's recently landed?
Before, the filecache cache key was just the core version IIRC, and now it's a hash of all installed packages.
Comment #71
godotislateNo. While the file cache will be invalidated more, because of package changes on disk or commits to the main project, the plugin discovery file cache won't be invalidated by Drupal cache clears or module (un)installs.
For example, uninstalling or installing Field UI won't invalidate the file cache.
Comment #72
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #73
godotislateRebased MRs after retarget to main branch.
Comment #74
joachim commented> No. While the file cache will be invalidated more, because of package changes on disk or commits to the main project, the plugin discovery file cache won't be invalidated by Drupal cache clears or module (un)installs.
Is the file cache something we can trigger the invalidation of?
Comment #75
godotislateWe'd basically be going the route @catch suggested before where the cache key includes the list of modules installed and the file cache is saved to DB instead of APCu, but there've been blockers to getting the file cache to work with DB storage.
Comment #77
smustgrave commentedSince it's been so long elevating to framework manager sign off.
Comment #78
godotislateI'm not sure that we need framework manager review.
One of the subsystem maintainers expressed their opinion via slack in #42, and their preference was for something like the approach in https://git.drupalcode.org/project/drupal/-/merge_requests/10668 allowing for arbitrary properties and values being added to the attribute. I probably should have removed the tag then. But it doesn't look like there's a lot of support otherwise that would make it seem worth doing all the work to finish it.
Comment #79
smustgrave commentedOnly elevated because it was tagged subsystem maintainer and if they don't respond we usually elevate. Can add that tag back if you want
Comment #80
godotislateMy point is that a subsystem maintainer did already review in #42, I just forgot to remove the tag.
Comment #81
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.