Problem/Motivation
DefaultFactory::getPluginClass()
does empty($plugin_definition['class'])
which fatals if $plugin_definition
is an object. In the entity and field system, where we actually have such plugin definition objects, we never use the DefaultFactory
but any contrib plugin type that tries to follow the supposed best practice of making its plugin definitions objects will fall into this trap.
Proposed resolution
Introduce an interface that object definitions should implement if their plugins are to be instantiated through DefaultFactory
.
Remaining tasks
None.
User interface changes
None.
API changes
None.
Blockers
This issue blocks #2458769: Derivative plugin definitions contain base plugin IDs instead of derivative IDs.
Beta phase evaluation
Issue category | Bug, because DefaultFactory cannot handle object definitions, while it should |
---|---|
Issue priority | Normal, because normal site operation is not affected |
Prioritized changes | Bug fix |
Disruption | No disruption |
Comment | File | Size | Author |
---|---|---|---|
#38 | drupal_2485513_38.patch | 12.53 KB | Xano |
#38 | interdiff.txt | 562 bytes | Xano |
Comments
Comment #1
tstoecklerNote 1: Because this is such an integral part of the D8 architecture I would consider this major but I'll let others fight that fight so marking normal for now.
Note 2: I must admit that I did not read through all the related issues in the plugin system queue, but I couldn't find anything for this particular bug using a bunch of targeted searches. Sorry if I missed something.
Comment #2
tstoecklerI was thinking something like this.
Should be straightforward to write a test for this, but I'd like some feedback first before pursuing that.
Comment #3
XanoMagic method access is not a solution, but a workaround. I know we're in a tight spot, but let's not 'fix' things the wrong way.
Comment #4
tstoecklerCare to share how you think it should be? ;-)
Comment #5
dawehnerI guess xano wants to have an interface ... #2458789: Introduce PluginDefinitionInterface
Comment #6
tstoecklerI agree with that issue. But I fear that will be more controversial and this is an actual bug. Marking "needs review" to get some more opinions on this.
Comment #7
XanoXano would like to see an interface, but he would even more so like to see we stop magically figuring out which properties or methods to call, like #2494719: ConfigFormBaseTrait is confusing. Such solutions only make things worse.
Ideally an interface, of course. I'm aware of the fact we are in code freeze right now, but that's no reason to commit workarounds that utilize very bad practices. We *can* still break BC to fix severe fundamental problems, which is why I don't want to rule out solving this issue (and several others) by adding the interface.
If this problem cannot be solved by introducing a new interface, then I have no potential fix in mind right now.
Comment #8
tstoecklerOK. If this does not get in before Drupal 8.0.0, @Xano owes me a $beverage. :-P
Comment #9
Xano#2458789: Introduce PluginDefinitionInterface now passes all tests and is ready for manual review. If that patch gets committed, fixing this issue will be really easy.
Comment #10
Fabianx CreditAttribution: Fabianx as a volunteer commentedTagging for framework manager review as #2458789: Introduce PluginDefinitionInterface was pushed back.
Comment #11
XanoTo re-iterate because this issue was referenced elsewhere: the patch is no workaround, but a hack. The new code is much more difficult to debug and will only work when object definitions work according to hardcoded, undocumented assumptions. I understand why it was proposed, but code like this should never be used.
Comment #12
XanoBump.
Comment #14
XanoWe shouldn't be using magic method access, even if it works in core's current configuration. See #11.
Comment #15
XanoThe only good solution involves working with an interface on entity/object definitions (reasons in #11). Seeing as this bug lives in
\Drupal\Component
, we cannot useEntityTypeInterface::getClass()
, unfortunately, as that lives in\Drupal\Core
. We can either introduce a new small generic interface, or pursue #2458789: Introduce PluginDefinitionInterface.Comment #16
XanoHere's a solution without magic or BC breaks. It works with entity types as well. I also fixed some left-over array access.
Comment #17
XanoI forgot to remove one more interface method.
Comment #18
dawehnerIMHO we should explain when to use it
What defines an invalid class?
Comment #19
XanoGood question. It depends on the plugin type, as most of them have interfaces that must be implemented, or base classes to be extended. I'll have to think about how to phrase this. Suggestions are welcome.
Comment #21
XanoChanged SHOULD to MUST as per @dawehner's recommendation, and added tests.
Comment #22
XanoSo I screwed up the patch after playing with Composer. Here's a clean one.
Comment #24
dawehnerThis kinda reverts the original idea of #2005716: Promote EntityType to a domain object which was about:
Comment #25
XanoEntity types have depended on plugins for as long as I can remember, at that issue didn't change that. I don't disagree that decoupling these two systems may potentially be a good idea, but the situation at the moment is that entity types are discovered through the plugin system, but that we don't really support object definitions properly. We're not going to change this dependency, as we don't only use plugin system classes, but have tied the entity API to the plugin system by at least making
EntityManagerInterface
extendPluginManagerInterface
andCachedDiscoveryInterface
. Changing this would be a BC break.TLDR; entity API depends on the plugin system and will do so until Drupal 8's EOL. Let's make sure this dependency works better than it does now.
Comment #26
lauriiiThe change looks nice compared to #2458789: Introduce PluginDefinitionInterface which caused quite bad BC breaks. In the patch, there is quite a good test coverage being added for the interface. We still need beta-evaluation, sign off from the framework manager and feedback about #24/#25
Minor detail; missing line change between namespace and use statement
Comment #27
XanoComment #28
Fabianx CreditAttribution: Fabianx as a volunteer commentedComment #29
XanoAddressing #26.
Comment #31
XanoRe-roll.
Comment #32
lauriiiEverything has been addressed from #26
Comment #33
tstoecklerYes, this looks awesome, thanks a lot!
The first placeholder is missing a "s". i.e. % -> %s
Assuming this can be fixed on commit, so RTBC++.
Comment #34
XanoLet's fix it now. The committers have more important things to work on than fixing typos :-)
We can use the newly added interface to fix #2458769: Derivative plugin definitions contain base plugin IDs instead of derivative IDs in the same way we fixed the bug here.
Comment #35
lauriiiThe size of patch increased quite a lot..
Comment #36
XanoI had forgotten to rebase. Here's the correct patch, plus interdiff (same as the previous one).
Comment #37
lauriiiComment #38
XanoLet's actually not require a fluent interface, to allow definitions to be immutable.
EntityType::setId()
can continue to return$this
, as that is covariant withstatic
.Comment #39
tstoecklerSure, whatever ;-P
Comment #42
XanoThat looked like a random test failure.
Comment #44
lauriiiComment #47
XanoRandom migration test fail.
Comment #50
XanoRandom HTTP query fail?
Comment #52
XanoThat was an aborted re-test. RTBC and triggering a re-test.
Comment #54
lauriiiComment #56
XanoComment #59
XanoComment #62
XanoComment #63
dawehnerLife is sad, but we should be honest. Entities are plugins, given that we use plugin manager interfaces. This coupling doesn't make things worse, it just shows it you directly.
Comment #64
alexpottI think this is a good compromise - we should be honest that we did truly decouple plugins and entity type discovery and this is a very minimal surface area. It also will make plugin managers that use objects for plugin definitions are more robust. I'm committing this under the committer discretion provision of the beta policy - but let's be honest - this is not a bug.
Committed 125cda4 and pushed to 8.0.x. Thanks!