Problem/Motivation
It seems that since DrupalCon Barcelona a yet unspecified change (possibly #2488568: Add a TypedDataManagerInterface and use it for typed parameters was made to Drupal core that caused \Drupal\Core\TypedData\TypedData
and child objects to contain the typed data manager. The class, however, does not prevent the manager from being serialized. This becomes a problem when adding fields to entities, and submitting the form.
Steps to reproduce:
- Install Payment 8.x-2.x.
- Add a Payment Form field to user entities.
- For best results, disable JavaScript.
- Edit your own account, and click Add and configure a new line item.
- Confirm that
\Drupal\Core\Database\Connection::__sleep()
throws an exception.
Proposed resolution
Potentially make \Drupal\Core\TypedData\TypedData
use \Drupal\Core\DependencyInjection\DependencySerializationTrait
. I have confirmed this fixes the bug, but it may not be the best possible solution.
Remaining tasks
Find the best solution and implement it.
User interface changes
None.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#36 | drupal_2615790_36.patch | 2.46 KB | Xano |
#36 | interdiff.txt | 976 bytes | Xano |
Comments
Comment #2
XanoThis is the suggested fix, but perhaps it's not the best one. We also need to find out how to test this. I'm not sure, especially because this looks like something our existing suite should have caught, considering its coverage and all the integration tests we have.
Comment #3
BerdirThis prevents the Payment module from working, so tagging accordingly. I don't think we need tests, it's relatively hard to test in a useful way. We already have unit tests for the trait.
We have this trait on entity, plugin and various other base classes.
Note that this is a minor BC break: subclasses that implement this trait already would get a annoying PHP strict notice (some sort of notice, I think it is strict) but it's very easy to fix. And not adding it can result in *very* hard to track down bugs.
Comment #4
BerdirAh, now I remembed where I've seen this before. It was in #2053415: Allow typed data plugins to receive injected dependencies, back then it was still a base class but same problem. We had to add it when we started to actually inject dependencies there.
TypedData now actually supports it but core doesn't use it much. But this will happen when someone actually uses that.
Comment #6
BerdirRetested, looks like a testbot issue.
Comment #7
ricovandevin CreditAttribution: ricovandevin at Finlet commentedI can confirm that the patch from #2 fixes this bug.
Comment #9
XanoComment #11
XanoComment #12
dawehnerThat bug is indeed really annoying!
This issue thought has a potential API break, right? What happens if other subclasses of TypedData had that trait already, for some reasons ...
Comment #13
Xano@alexpott suggested this approach to limit the BC break.
Comment #14
BerdirA comment would be great, and possibly the @todo for 9.x that @alexpott mentioned to use the trait?
Comment #15
dawehnerYeah we better need a comment but yeah I really tried that on debugging some contrib module and something conflicted when you just put it into TypedData using the trait before ...
... What about adding a weekup method as well?
Comment #16
catchAs well as the @todo is it worth a new Base class that does use the trait?
Comment #17
BerdirYou usually don't extend from TypedData directly, but from e.g. FieldItemBase, so I'm not sure how much that would really help.
Comment #18
XanoWe do not need to implement
::__wakeup()
, because\Drupal\Core\TypedData\TypedDataTrait::getTypedDataManager()
lazyloads the typed data manager.Comment #19
Xano::sleep()
did not return an array if strings, but none of our tests caught that. I noticed this when running contrib tests (the same that exposed this bug in the first place).Comment #20
XanoWe had one more service to unset before serialization. I tested this using Payment, and all its tests pass with this patch applied.
Comment #21
dawehnerDo you mind adding a quick test to ensure this actually works?
serialize($entity->name)
should be enough.Comment #22
XanoComment #27
XanoThanks to Simpletest for being communicative.
Comment #29
dawehnerLooks good even I haven't see the $sut thing
Comment #30
alexpottI think is quite a big assumption that any other test methods added to this unit test will need the same mocked class. Therefore lets get rid of the introduction of sut - the world does not need more tlas to get in the way of understanding stuff - and just do everything in the testSleep() method with no properties.
Comment #31
XanoComment #32
XanoComment #33
BerdirPer our IRC discussion, lets use a different variable name, $typed_data or something.
Comment #34
XanoSUT is a known acronym for these things. I advocate in favor, because using different names for the system under test in different tests is unnecessarily confusing when reading the code line by line.
Comment #35
BerdirStill has $serialized_sut in there ;)
Comment #36
XanoComment #37
BerdirThank you.
Comment #38
catchCommitted/pushed to 8.1.x and cherry-picked to 8.0.x. Thanks!