Problem/Motivation
\Drupal\Core\Plugin\DefaultPluginManager::findDefinitions() checks for a 'provider' key in the plugin definition array, and removes the definition if the provider does not exist.
However not all plugin definitions are arrays. It attempts to handle this by casting the object to an array, but that only works if there is a public $provider; property in the definition class, which is not ideal.
Proposed resolution
Expand \Drupal\Component\Plugin\Definition\PluginDefinitionInterface.
Previously discussed was adding a new interface, and deprecating PDI.
However, multiple issues want to expand PDI, we can't just introduce a single new interface that replaces it. We'd end up with a confusing circular dependency of which interfaces to use when and which would be deprecated.
@catch cited that problem, and https://www.drupal.org/core/d8-bc-policy, to suggest that we just expand PDI directly
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #32 | 2818653-pdi-32.patch | 12.23 KB | tim.plunkett |
| #32 | 2818653-pdi-32-interdiff.txt | 1.33 KB | tim.plunkett |
| #21 | 2818653-pdi-20.patch | 12.07 KB | tim.plunkett |
| #20 | 2818653-pdi-20-interdiff.txt | 3.09 KB | tim.plunkett |
| #19 | 2818653-pdi-19-interdiff.txt | 6.35 KB | tim.plunkett |
Comments
Comment #2
tim.plunkettComment #3
eclipsegc commentedOk, this seems pretty sane... Test coverage?
Eclipse
Comment #4
tim.plunkettYep
Comment #5
tim.plunkettLet's have EntityType get this benefit. Their provider hasn't been getting checked
Comment #7
eclipsegc commentedLooks sensible and useful to me!
Eclipse
Comment #8
alexpottThis needs a 9.0.x issue and also should be more than an @todo. Also this issue should have a change record.
Comment #9
tim.plunkettAlso while testing this patch out on some actual code, realized we should update \Drupal\Core\Plugin\PluginDependencyTrait as well.
Comment #10
tim.plunkettFor #9, #2821191: Allow object-based plugin definitions to be processed in PluginDependencyTrait is now it's own issue.
#2485513: DefaultFactory cannot deal with objects as plugin definitions was the issue that added PluginDefinitionInterface. The only implementor is EntityType (and now the experimental LayoutDefinition), all other plugin definitions in core are arrays.
That issue was championed by Xano, who is responsible for the contrib Plugin module. It contains a multitude of helpers, decorators, and workarounds for core's lack of support of object-based definitions.
For example, they have their own version of PluginDefinitionInterface which already contains this method.
Because both #2821189: Allow object-based plugin definitions to be processed in DerivativeDiscoveryDecorator and this issue want to expand PDI, we can't just introduce a single new interface that replaces it. We'd end up with a confusing circular dependency of which interfaces to use when and which would be deprecated.
@catch cited that problem, and https://www.drupal.org/core/d8-bc-policy, to suggest that we just expand PDI directly.
Comment #11
tim.plunkettComment #12
tstoecklerThis looks absolutely great.
Would be nice to provide this as an actual
PluginDefinitionclass in a non-test namespace for object-based definitions to extend. That should be a follow-up, let's get this in first.Also added change record, so this is good to go, IMO.
Comment #13
alexpottThis change looks very sensible. The one concern I have is for contrib that has implemented
\Drupal\Component\Plugin\Definition\PluginDefinitionInterface. The comment in #10 allays a few of the concerns but I think the issue summary needs an update to reflect the changes made by this issue and to mkae the case for this change in 8.3.x. I'm not convinced that the plugins section on https://www.drupal.org/core/d8-bc-policy actually covers this case.Comment #14
tim.plunkettComment #15
tim.plunkettComment #16
jibran#13 addressed in #15 so back to RTBC.
Comment #17
effulgentsia commentedThe plugins section doesn't, but I think that https://www.drupal.org/core/d8-bc-policy#interfaces does. From there:
I think it's a shame that we didn't add a
PluginDefinitionTraitwhen we addedPluginDefinitionInterface. But that's because we addedPluginDefinitionInterfaceprior to the above BC policy clarification. I think it would be good though to provide that trait now, so that even though we inconvenience some contrib authors with this change, at least they'll be able to opt in to the trait and then not be inconvenienced again when we add another method in the future. I'm not necessarily opposed to punting the trait to a follow-up, but I'd feel better with committing it as part of this patch, so that the CR can instruct people about it.Comment #18
effulgentsia commentedThat might be more sensible than a trait in this case. Since LayoutDefinition, EntityType, etc. do have a "is a" relationship to plugin definitions, so a base class is logically appropriate here, I think.
Comment #19
tim.plunkettComment #20
tim.plunkettFixed a doc line that was because of the shift from #17 to #18.
Also, after checking on what the plugin.module provides in it's base class, adding id(). This was also already in LayoutDefinition and EntityType.
This plus #2821189: Allow object-based plugin definitions to be processed in DerivativeDiscoveryDecorator gets us to a really good place.
Comment #21
tim.plunkettUgh.
Comment #23
tim.plunkettStill targeting this for 8.3.x
Raising to major as it is no longer just a soft blocker, but is blocking issue for the Layout Initiative, specifically for #2844302: Move Field Layout data model and API directly into \Drupal\Core\Entity\EntityDisplayBase
Comment #26
jibranI think instead of typcasting to array either use Reflection or check for toArray and as third choice convert typecast to array.
Comment #27
tim.plunkett- if (is_object($plugin_definition) && !($plugin_definition = (array) $plugin_definition)) {I'm not adding the cast just moving it.
No such method as toArray.
Adding reflection is out of scope.
Comment #28
jibranFair enough!
Comment #29
tstoecklerThis is confusing. Usually this is the plugin ID, the plugin definition itself does not generally have a distinct ID. The documentation needs to be updated to reflect that.
Also this should be
getId(), notid(). I realize that the latter is whatEntityTypeuses, but this is a new interface so we should be using best practice naming here, IMO.Marking needs work for the first point at least, I realize the last point is potentially contentious.
Comment #30
tstoecklerComment #31
tstoecklerComment #32
tim.plunkett#2350807: add getId() and make id() a wrapper for it and deprecate it is for the getId() vs id() portion. This is not really in scope here, it should be a single discussion and break.
Good point on the docs! Fixed. Also removed the duplicate declaration of EntityTypeInterface::id()
Comment #33
tstoecklerThanks, awesome that we already have dedicated issue for the getId() vs. id() thing. Docs look perfect now.
Comment #34
effulgentsia commentedPatch looks great to me. Ticking some credit boxes.
Comment #37
effulgentsia commentedPushed to 8.4.x and cherry picked to 8.3.x. Let's update the CR to mention the id() method and base class and then publish it.
Comment #39
quietone commentedpublish the change record