Problem/Motivation
To reproduce:
1. Enable rest, hal, language, content_translation on a standard profile.
2. Enable a second language (German) and make the node type "page" translatable with all fields.
3. Save the attached JSON text file (generated by NodeHalJsonCookieTranslationsTest).
4. Enter the Drupal console and use the following commands:
$serializer = \Drupal::service('serializer');
$data = $serializer->decode(file_get_contents('JSON_FILE'), 'hal_json');
$node = $serializer->denormalize($data, 'Drupal\node\Entity\Node', 'hal_json');
The deserialized node's translation contains values for all "default" items (status, sticky, created, changed, langcode, etc.)
print count($node->changed); // 1
print count($node->getTranslation('de')->changed); // 2
The duplicates increase each time the node is normalized and denormalized.
$node = $serializer->denormalize($serializer->normalize($node, 'hal_json'), 'Drupal\node\Entity\Node', 'hal_json');
print count($node->changed); // 1
print count($node->getTranslation('de')->changed); // 3
$node = $serializer->denormalize($serializer->normalize($node, 'hal_json'), 'Drupal\node\Entity\Node', 'hal_json');
$node = $serializer->denormalize($serializer->normalize($node, 'hal_json'), 'Drupal\node\Entity\Node', 'hal_json');
print count($node->changed); // 1
print count($node->getTranslation('de')->changed); // 5
This looks like a bug in the field denormalization which causes it fail to properly clear default values.
Tested on 8.5.x and 8.3.7. This is causing test failures in #2135829: [PP-1] EntityResource: translations support.
Proposed resolution
Avoid the field value duplication.
Remaining tasks
- Get patch to green.
- Review.
- Commit.
User interface changes
None.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#90 | interdiff-87-90.txt | 8.98 KB | ilya.no |
#90 | 2904423-90.patch | 4.84 KB | ilya.no |
#87 | diff-2904423-84-87.txt | 1.29 KB | cburschka |
#87 | 2904423-87.patch | 5.1 KB | cburschka |
#84 | 2904423_84.patch | 5.09 KB | mkalkbrenner |
Comments
Comment #2
tedbowI am going to try writing a test that takes the code from issue summary proves the bug.
Comment #3
cburschkaFrom what I can see in the debugger, the problem is the following:
1.
$field_item_list->setValue([]);
(fromFieldableEntityNormalizerTrait::denormalizeFieldData()
) empties out the base entity to prevent the same problem happening there.2. But the translated entity is basically created on demand the first time the denormalizer hits a translated field in the right langcode.
FieldItemDenormalizer::denormalize
calls::createTranslatedInsance
which callsNode::addTranslation
, which sets the default values.Now ideally, ::createTranslatedInstance could simply empty out the field before it appends a new item, but we can't do that, because this part of the code runs for every item in that langcode, so we'd overwrite past values.
One solution may be to wrap the ::addTranslation call into a separate function on the FieldItemDenormalizer, which should empty out all of the newly created entity's fields at once. After that, we can safely append the new field items as we find them.
Comment #4
cburschkaThanks! I'll attempt to write the fix.
(Note: The HAL and REST modules are probably not necessary for the test, as this bug occurs in the serialization module itself. However, denormalizing
json
instead ofhal_json
format seems to require a somewhat different JSON string than the one I uploaded.)Comment #5
cburschkaThe simplest approach (attached) doesn't work because the ContentEntityBase::onChange() method protects the langcode field against change (see #2443989: Allow the entity translation language to be changed).
That's a special case, though - as it is automatically set and unchangeable, we can simply skip this field both in ::createTranslatedEntity and during denormalization. If we want to be extra careful, we might enforce that on denormalizing
{"value": "X", "lang": "Y"}
, X must be equal to Y.Comment #6
cburschkaThis patch avoids appending an item on singular-valued fields, and also empties all fields except for the langcode when creating the translation.
I'm really not sure about the approach here, though...
(The first part fixes everything except multi-valued fields with default values. The second part fixes everything except for the langcode. So there's some significant redundancy there, even though neither is enough on its own.)
Comment #7
tedbow@cburschka thanks for the patch. I was working on the test separately. I am uploading a test only patch that proves the problem and then a patch with #5 added. I don't think if fixes the problem but haven't had a chance to look.
The test I should be moved probably to the serialization module and then have test in HAL that extends it and just changes the format.
Comment #10
cburschkaHere's #6 + the test in #7, with @group annotation.
Comment #12
cburschkaAnd once again, with the @group annotation on the right class this time.
Comment #13
cburschkaTest-only, with group.
Comment #16
cburschkaSo the test does find the bug in hal_json, and the fix repairs it.
However, the test finds another problem in that denormalizing non-hal json doesn't seem to work with translations at all (not sure if that's a bug).
Also, the fix introduces problems in denormalizing the path field during other denormalization test (NodeHalJsonAnonTest and others).
Comment #17
Wim LeersThis bug is exactly why we need test coverage. Which is why we're doing #2135829: [PP-1] EntityResource: translations support. But that's where this was found. So, yay — we're working on the right things!
This is similar to what we do in
\Drupal\serialization\Normalizer\FieldableEntityNormalizerTrait::denormalizeFieldData()
. The difference is that that operates at the entity-field level, this operates at the field-property level. So this makes sense.So let's make the test coverage only work for the
hal_json
format for now. Ensuring translated entity support works in all formats and all situations is out of scope here. This issue is only about fixing this one bug.Great work here!
Comment #18
tedbowChanging test coverage to be only for
hal_json
format and changing component to hal.moduleComment #20
tedbowAll of the test failures I think have to do with the Path field which is computed. So I am pretty sure we should not be executing this new logic for computed fields.
Comment #21
Wim Leers#20:
Comment needs to be updated. And actually… wouldn't it make more sense to never denormalize computed fields in the first place? Shouldn't the denormalization process simply ignore them? If they're computed, then they shouldn't be sent?
The test coverage only covers the first case: if the translation already exists.
Whitespace nit.
Comment #22
cburschkaGreat work!
I agree that we'll need a different approach for the computed fields than this. It's true that #20 fixes the NodeHalJsonAnon failure in the "path" field. But if we cross-test with #2135829: [PP-1] EntityResource: translations support, we see that the same failure still happens when we are actually PATCHing a multilingual node.
Specifically:
- NodeHalJsonCookieTranslation (added by that issue) currently fails both on the "changed" and "path" fields (the latter if you manually skip the access check on "changed").
- Applying #20 fixes the "changed", but it still fails on "path".
Unfortunately, it's probably not that simple. "computed" doesn't mean "read-only" - in this case, the path field writes to the alias table on ::postSave, making it simply a field with custom storage. So if you have the required permissions, it certainly makes sense to PATCH a node and change computed fields like the URL alias. It's up to the individual field plugin to restrict access if the field really shouldn't be changed.
Actually, since we create a blank entity when denormalizing, it doesn't have any translation until the denormalizer adds it. We hit the "false" branch in this line every time we denormalize the first field item in a new language, and the "true" branch thereafter.
Edit
Debugging details: Investigation shows that without the patch, and with #20, NodeHalJsonAnon's problematic PATCH denormalizes an entity where the field has one (correct) value; with #18, it has an empty and a correct value. Haven't tested yet what happens with NodeHalJsonCookieTranslation.
Comment #23
Wim LeersD'oh, true. Reminds me of #2392845: Add a trait to standardize handling of computed item lists.
Conclusion: what I wrote in #21.1 is wrong, and so is #20's interdiff, right?
Comment #24
cburschka(Edit before posting: Yep - skipping the entire ::createTranslatedInstance call for computed fields isn't right.)
-----------
The new problem is not the ::createTranslatedEntity (which only happens on non-default languages anyway), but rather the innocuous-seeming logic for non-multiple fields.
The Path field is lazy-loaded, and starts out with isLoaded set to false.
The FieldNormalizer automatically adds an item, which we then get rid of in FieldItemNormalizer::createTranslatedEntity.
But at that point, the field has no items.
Then we hit
But ::isEmpty() causes the lazily-loaded field to call PathFieldItemList::ensureLoaded(), and automatically create a stub item. (It doesn't load data yet; that's done by the item instance itself on demand.)
And then we append a new empty item, bringing the total to two.
So the lessons are 1) ::isEmpty() isn't free of side-effects, and 2) ::isEmpty() returning true doesn't mean that the field's item list is empty; it might contain an instance with a null value.
I suspect what I should have used there is not ::isEmpty() but rather !count(). As far as I can tell, this returns the list's length without side effects - and even if some field plugin ever overrides it to do stuff, we should be able to assume that its return value will match the new list length.
Comment #25
cburschkaThough as per #6.3, we only really need the condition at all for one special case - the langcode field, which we aren't able to unset in ::createTranslatedEntity, and which we therefore shouldn't append a new item to.
If we can deal with that case in some other way, this extra check wouldn't be needed.
Comment #26
cburschkaComment #28
tedbowWell this is tricky problem....
#24
I think you actually just found a bug with PathItemList. Count and isEmpty should act the same or at least count() should act the same whether you call it before or after a call to isEmpty which it doesn't
See this example from my tester module:
It shows that calling count() behaves differently after isEmpty() has been called because it calls ensuredLoaded and creates an item. So this is a bug in PathItemList and we can't rely on count() here to tell if it is empty.
UPDATE: I have to step out for a bit so can't file this bug issue. I will when I get back or if someone else does please report back here. Thanks
Comment #29
tedbowHere is the issue for the bug described in #28 #2905524: The count() method used on PathFieldItemList behaves differently if isEmpty() has been called.
If I am wrong and that is expected behavior we can just close that issue.
Comment #30
Wim LeersRight, it's totally possible that
PathFieldItemList
is not entirely correct. It was introduced in June in #2846554: Make the PathItem field type actually computed and auto-load stored aliases. But since it's the first of its kind (a field item list object specifically for a computed field that isn't really computed, but just backed by custom storage), it's totally understandable that there are oversights. A week ago, we already fixed one thing aboutPathFieldItemList
: it needed to also override the::equals()
method (in #2824851: EntityResource::patch() makes an incorrect assumption about entity keys, hence results in incorrect behavior).Pinging @Berdir, since he's one of the people who know best how translated entity fields are supposed to work, plus he helped introduce
PathFieldItemList
. I think we need his guidance here.Comment #31
cburschkaThat's right, count() should probably call ::ensureLoaded().
(Fixing that bug shouldn't cause problems for this patch, as long as count() still behaves like ItemList::count and returns the length including empty items. It'll just mean that instead of returning 0 and letting us append an item, it initializes the item itself and then returns 1.)
Edit:
The new test failure is also on the path field, but this time it seems to be the opposite - the patch field isn't changed, despite a new value being entered.
Comment #32
cburschkaOh wow, this new failure's a bit... funny.
From EntityResourceTestBase::getModifiedEntityForPatchTesting() (var_dumps added by me):
So yeah, the lesson this time is that just because a test is passing, it doesn't necessarily work correctly. :D
(Explanation: FieldItemList::getValue() returns [0 => [alias => ...]] rather than [alias => ...]; the test modifies this to [0 =>[alias => ...], alias => ...], then passing this invalid array to PathFieldItemList::setValue somehow turns it into a list containing the original item twice. The test still passes because this counts a "modified" value for the field. But since #26 automatically discards multiple values for non-multiple fields, it stops passing.)
(In fairness, this code is barely a week old from #2824851: EntityResource::patch() makes an incorrect assumption about entity keys, hence results in incorrect behavior, so I can see how this hasn't been caught yet.)
Comment #33
Wim LeersThis is blocking #2135829: [PP-1] EntityResource: translations support, tagging
blocker
.Comment #34
cburschkaComment #35
Wim LeersWoot! Looking forward to your patch 🙂
Comment #36
cburschkaOkay, for a start I'll just retest #26 now that #2824851: EntityResource::patch() makes an incorrect assumption about entity keys, hence results in incorrect behavior has been reverted, since that was causing one of the failures before.
Comment #37
cburschkaLooks like the test for #26 passes now.
As far as I can tell, the count() bug described in #28-31 should not require a change to this patch, and the problem in #32 was simply exposing a bug elsewhere (which will need to be fixed separately).
Comment #38
tedbowThis block is confusing to me because we are checking if the field is empty or allows multiple values before appending another item.
Instead of isMultiple() should we also be checking ?
Comment #39
Wim Leers#36:
:( Do we understand why? Why did it only cause failures for
Node
entities, and then even only for thehal_json
format? How do we ensure that this failure doesn't reappear when #2824851: EntityResource::patch() makes an incorrect assumption about entity keys, hence results in incorrect behavior is recommitted?Hm, #28 and #29 seem to suggest this is related to the computed path field behaving incorrectly. That's fortunately being fixed in
#2916300: Use ComputedFieldItemListTrait for the path field type, which is blocked on #2392845: Add a trait to standardize handling of computed item lists.
Based on my analysis above, I think you're right.
#38:
Good question! This is indeed confusing. Let's look at
FieldStorageDefinitionInterface
for an answer. It contains these:Which is still a bit confusing. But the actual implementation actually makes it very clear:
Which means @tedbow is right, this should be essentially checking
Comment #40
tedbow@Wim Leers thanks for analysis!
I change you suggest code slightly to
if ($cardinality === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || count($field) < $cardinality) {
We don't need to check both
!count($field)
ANDcount($field) < $cardinality)
Since
\Drupal\Core\Field\FieldStorageDefinitionInterface::getCardinality
docs stateThe only way
count($field) < $cardinality)
will ever be checked is if$cardinality !== FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
.Since
count()
returns back an integer just checking if it is less than$cardinality
works.Comment #41
Wim Leers👌 Even better!
You forgot to update the comment. Once that's updated, this is RTBC.
Actually, thinking about it — I don't think a comment is necessary!
Comment #42
cburschkaAwesome! =)
Comment #43
cburschkaComment #44
Wim LeersComment #46
cburschkaI'm not sure I understand the test log, but
Unknown database 'jenkins_drupal_patches_37878'
doesn't look like a legit failure.Comment #47
tstoecklerSorry for jumping so late on this, but this caught me a bit by surprise.
It seems that if we have to do this, we are working around some other, deeper issue. Looking at the patch and thinking about it a bit, I think that deeper issue is that the field item normalizer somehow has to decide where in the field item list the field item it is denormalizing belongs. That should not really concern a field item normalizer, however. Instead, shouldn't the field item list normalizer decide which field items go where - i.e. which field items go into which translation in which order - and then delegate to the field item normalizers that don't have to do any magic?
I.e. turn
\Drupal\hal\Normalizer\FieldNormalizer::normalizeFieldItems
into something like (untested):That way this whole HAL-specific langcode handling is completely opaque to the field item itself and is fully handled on the list level.
Thoughts?
Comment #48
tstoecklerComment #49
Wim LeersI think that's a really good point! We'll look into that. Thanks for pointing that out! 👍😀
Comment #50
tstoecklerHere's a start on what I was thinking. It passes the test added in this issue at least, not sure if/what it breaks anything else. I probably won't be able to drive this home (in case it's viable), but I thought I should at least provide some starting point here, since I knocked back an already RTBC patch. The patch also contains two "@TODO"'s, so it's definitely work-in-progress.
Comment #51
tstoecklerActually, the second @TODO in my patch kind of stuck in my head, and I now think that it make even make more sense to move the entire translation-related logic to
ContentEntityNormalizer
.The received data, that we want to denormalize has the following structure:
And the way we structure our entity objects in memory requires to restructure that into:
(Of course the deltas will be recreated so that both translations then have 0 and 1 as deltas, but I wanted to make the link to original structure clear.)
Now since we denormalize from the outside in, we need to decide at which level in the structure we to the translation setup. The patch in #42 does this at the field item level, and my patch in #50 does it at the field item list level, but looking at the above, it seems sensible to actually do this at the entity-level itself and then just pass the correct field item list values to the correct translation.
Thoughts?
Comment #53
Wim Leers#51 I think you're right!
However, let's not forget that this is HAL-specific, and we're working in the
hal.module
component. In the HAL normalization, each delta has alang
key-value pair, which is why it's possible at all to send all translations simultaneously. That may not be possible in other normalizations.That's fine, I just wanted us all to remember that.
I went to look at the HAL spec, and unfortunately … I found exactly zero mentions of how to deal with translations/languages: https://tools.ietf.org/html/draft-kelly-json-hal-08. So it seems this is a Drupalism we added to HAL :( It was introduced in #1924220: Support serialization in hal+json. And #1931976: Support deserialization for hal+json (needs more language handling tests) was supposed to add denormalization support, which it did. But then it still needed a test to prove that denormalizing normalized data actually worked (which it obviously does not), which never happened. Otherwise we wouldn't have this issue.
Comment #54
Wim LeersHaving written #53, I realized something. #51 means that the normalizer is no longer dealing with the data/value object it is given, and then passing the next level on to the (de)serializer service again (which is the primary design element of the Symfony Serialization component). It means we're bypassing/working around/not using/not conforming to the very architecture we signed up to use.
Then my eye fell on this bit in the IS of #1931976: Support deserialization for hal+json (needs more language handling tests):
This was written 4.5 years ago, by one of the architects of D8's REST API. IOW: it was already decided back then to not conform to the very architecture we signed up to use. 😱
The more skeletons I encounter in the closest, the more I wonder how D8 shipped with a "stable" REST module. 🤐
So … while I think #51 is a great idea, I fear it may actually out-of-scope refactoring. #42 was merely fixing the existing code, and the existing code may have architectural flaws that only become clear now, but it's architecture introduced by the WSCCI architects in #1931976: Support deserialization for hal+json (needs more language handling tests) (that's the issue that introduced
\Drupal\hal\Normalizer\FieldItemNormalizer::denormalize()
). Therefore I think it may be better to go with the patch in #42 after all, because it doesn't change the existing architecture as much, which means there's less risk.After all, this is merely a small blocker/bug discovered while we're working in #2135829: [PP-1] EntityResource: translations support to add test coverage for the existing
hal_json
format's (supposed) support for translations. So I think it's best to minimize change, and once that test coverage is in, it'll be far less risky to make significant architectural changes like the one you proposed in #51, but also the one you proposed in #47/#50.Sorry for the comment rollercoaster :( I first tentatively agreed with you (in #49), then agreed with you even more (in #53), and now end up not agreeing at all, after doing more research. I hope all this made sense. I know it's tricky/confusing, but that's part of making kinda-working-but-mostly-broken things work again, unfortunately! I *do* appreciate your reviews on this enormously. I'm looking forward to reading your reply, perhaps you'll still convince me of #51 after all :P
Comment #55
tedbow@tstoeckler thanks for the reviews! @Wim Leers thanks for looking into the background.
I agree with @Wim Leers in #54. I think it makes sense to change as little as possible. There is obviously a bug in the denormalization process but from #1931976: Support deserialization for hal+json (needs more language handling tests) it seems the original intention should was to happen on the field item level. It seems we should not change this.
Custom code could also be overriding the
FieldNormalizer
for some small change and if they looked at the current code they would interpret that Translation does not need to be handled on this level. I think we should only change this if it is not possible to handle translations on the FieldItem level.If we can get it working with minimal changes we can move onto [#32135829]
Comment #58
aken.niels@gmail.comI've tried to plow through this issue and seem to get some of the problems, though it seems to me like a true rollercoaster and am a bit confused on how this issue should proceed? We're having a project that needs REST API in combination with translations badly and seems to be stuck on #2135829: [PP-1] EntityResource: translations support and / or this issue. As I've come to understand, currently CRUD operations on translated nodes is a no-go because the normalization process in this part is questionable? Does this still needs work? Or is this a "works as intended"?
I'd be happy to help in this matter (if I can), since we desperately need REST API to work with content translations. But at this point I'm a bit confused about the status and this hasn't been updated for a while. I'l also post a followup on #2135829: [PP-1] EntityResource: translations support, since that has been stale as well for quite some time.
Edit: After digging around some more, I noticed that there are some conceptual problems to be considered. At this point it's questionable if HAL+JSON should actually handle any POST / PATCH requests, as noted in #1931976: Support deserialization for hal+json (needs more language handling tests) which refers to #1929632: Decide how to handle POST/PATCH when using HAL. The last mentioned issue seems to be stale for years. Also, the mentioned message boards in them are really old. I'm starting to think this has hit a brick wall on whether or not HAL should support POST / PATCH?
Comment #59
Wim Leers#2135829: [PP-1] EntityResource: translations support is the general translation support issue for core REST, for all formats:
json
,xml
andhal_json
.However, while working on that, we discovered a serious bug in the HAL normalizer that blocks progress in the aforementioned issue: that's what #2904423: Translated field denormalization creates duplicate values is for.
Comment #60
aken.niels@gmail.comThanks for the response. Alright, #2135829: [PP-1] EntityResource: translations support is for general translation support, does that mean that that issue is postponed only because of the hal implementation and therefor all other formats? Before making this into a really long discussion and going to much off-topic, would you mind discussing this with me on Slack? :-)
Comment #61
Wim LeersOh, and yes, #1931976: Support deserialization for hal+json (needs more language handling tests) is the weird/incomplete solution that got committed but then left open for test coverage for years… and I had never even seen #1929632: Decide how to handle POST/PATCH when using HAL — how the hell did you find that!? 😮 👏
Regarding why this issue exists, see #2135829-106: [PP-1] EntityResource: translations support and preceding comments. @cburschka discovered a bug, and hence filed this issue. This issue indeed affects only the HAL implementation, but then gets in the way of uniformly testing translation support across all formats. We want to have the translation test coverage work across all formats, and therefore this bug needs to be fixed first.
Comment #62
aken.niels@gmail.comPretty easy, that issue was mentioned in #1931976: Support deserialization for hal+json (needs more language handling tests) in it's description. 😅
Alright, I now understand that this issue was created during development of #2135829: [PP-1] EntityResource: translations support and that that issue needs this fixed first to be able to test all formats. This got stalled though and I'm not entirely sure why. Is this still open on conceptual problems that have to be thought over? Or is this postponed by other issues? Or is this simply ready to be developed? If so, are any of the patches in this issue still relevant? (sorry for being dense, I'm trying to get a clear view on this 😅)
Comment #63
cburschkaAccording to #54 and #55, it seems like the remaining architectural problems are older/bigger in scope than this issue, and for fixing the bug the approach in #42 would be sufficient.
There was a small line conflict in the meantime, so here is a reroll/merge.
Comment #64
cburschkaComment #65
aken.niels@gmail.comAs far as my two cents are worth; tests seem to pass nicely and I've tried reproducing the original reproduction steps in the description. Without the patch I indeed see the duplicate values, after applying the patch, I do not get the duplicate values. So that seems to do the trick.
Disclaimer; I haven't looked at the contents of the patch.
Comment #66
finneI found this issue when denormalizing content_translation_source fields on nodes. The node and its translation are present in the HAL JSON data and this gets denormalized, but then the content_translation_source field will contain the default value [und] and the value from REST [nl in my case]. As the field only accepts 1 value, the REST data is discarded.
When applying patch #63 on D8.6.1 the content_translation_source field contains the correct values. But I get an error saving the denormalized entity: "Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'default_langcode' cannot be null: INSERT INTO {node_field_data} (nid, vid, type, langcode, status, title, uid, created, changed, promote, sticky, default_langcode, revision_translation_affected, content_translation_source, content_translation_outdated"
This is because patch #63 introduces the function createTranslatedEntity() which unsets all translatable field values. The default_langcode is not processed to refill these field values because it is used to determine the language to use to create the entity in its base language in \Drupal\hal\Normalizer\ContentEntityNormalizer::denormalize and is then discarded.
Comment #67
finneI solved the problem of #66 by not unsetting $data[$default_langcode_key] in the ContentEntityNormalizer. This way the REST data in the default_langcode is applied to each translation of the entity. The attached patch is based on patch #63 and only adds the removal of the usetting of the $data[$default_langcode_key] in the ContentEntityNormalizer.
Comment #68
j1mb0b CreditAttribution: j1mb0b commentedFor my case I have had to get a working solution for a project.
I have cross tested the patch https://www.drupal.org/files/issues/2018-07-25/2135829-120.patch from issue #2135829: [PP-1] EntityResource: translations support with #67.
Comment #69
askibinski CreditAttribution: askibinski commentedHere is a reroll against 8.6.10.
Comment #72
vacho CreditAttribution: vacho at Skilld commentedPatch ported to 8.8.x version
Comment #73
andypostComment #78
TrevorBradley CreditAttribution: TrevorBradley commentedNot sure if one report is enough to get it over the line of RTBC, but I can report that applying this patch beautifully fixed a number of issues with Default Content Deploy - issues with translation of metatags and creation/revision dates being improperly imported.
It also still applies cleanly to Drupal 9.2.
Comment #79
mkalkbrennerAt Jarltech we can't use default_content_deploy without the patch in #73.
I set this long time issue to RTBC to get it reviewed by a core maintainer.
Comment #80
alexpottThe patch in #72 is missing the tests from #63. We shouldn't be fixing bugs without a test that proves the bug is fixed and ensures we don't break it again.
Comment #82
mkalkbrennerI re-added the tests to the latest patch.
Comment #84
mkalkbrennerComment #85
cspitzlayThe test from #63 has been added and the tests are green again.
Comment #86
cburschkaNeeds a (probably small) reroll due to bd858c231315ceea3c41583e70f9bb44d314b455 from #3252872: Use CacheableSupportsMethodInterface for performance improvement in normalizers.
Comment #87
cburschkaCan't easily interdiff a merge, but here's a diff of patches 84-87 that seems to show it was just a tiny context change.
Comment #89
SpokjeThe
hal
module has moved out of Drupal Core and into a Contrib Module.Moving this issue to the Contrib Module queue.
Comment #90
ilya.no CreditAttribution: ilya.no as a volunteer and at Skilld for Skilld commentedAttaching patch for contrib module.