Problem/Motivation
function foo_entity_delete(EntityInterface $entity) {
$context = EntityContext::fromEntity($entity);
}
This will fail.
There is a @todo comment in InlineBlockEntityOperations::handleEntityDelete():
public function handleEntityDelete(EntityInterface $entity) {
// @todo In https://www.drupal.org/node/3008943 call
// \Drupal\layout_builder\LayoutEntityHelperTrait::isLayoutCompatibleEntity().
$this->usage->removeByLayoutEntity($entity);
}
This comment was added in #3026434: Ensure that Layout Builder Inline Blocks doesn't assume section storage internals to deal with how a call isLayoutCompatibleEntity() on the entity being deleted eventually causes an error in \Drupal\Core\Entity\Plugin\Validation\Constraint\ValidReferenceConstraintValidator::validate() (loading entities in the validator introduced in #2791269: Allow saving pre-existing references to inaccessible items).
Proposed resolution
If \Drupal\Core\Entity\Plugin\Validation\Constraint\ValidReferenceConstraintValidator::validate() can't load the unchanged entity from the DB (because it no longer exists), use the one we have
Since $this->usage->removeByLayoutEntity($entity) just performs a simple update query, loading entities to check whether they can be deleted likely does not offer any benefit or performance enhancement, so the isLayoutCompatibleEntity is unnecessary.
This ticket is now a clean up to remove the todo comment in InlineBlockEntityOperations::handleEntityDelete()
Remaining tasks
N/A
User interface changes
N/A
API changes
N/A
Data model changes
N/A
| Comment | File | Size | Author |
|---|
Issue fork drupal-3008943
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 #2
tim.plunkettComment #4
amateescu commentedI wonder what's the use case for validating an entity after it has been deleted from the storage. The issue title says that the entity is being deleted, but that's not really accurate, the entity is already gone.
Comment #5
tim.plunkettIt's not actually the validating I'm hitting, it's
EntityContext::fromEntity($entity), which is easily triggered that way.When a custom block is deleted, Layout Builder has to find all of the usages of that block in order to remove the reference to it. See #2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder, and
layout_builder_entity_delete()/\Drupal\layout_builder\InlineBlockEntityOperations::handleEntityDelete().Because TypedData, everything all the way down the chain, even the now-deleted block, is instantiated.
Comment #6
phenaproximaI think the test could benefit from a comment explaining why we're calling validate(), but otherwise this looks good and is ready to go.
Comment #7
tim.plunkettNah, let's just be explicit about what we're testing. No need to mess with ::validate()
Comment #8
tim.plunkettHere's a pass/fail version, to prove we're actually still testing it without the validate() part
Comment #9
phenaproximaI like it. RTBC on the assumption that it will look like Christmas in an hour.
Comment #11
amateescu commentedI'd like to take another look at the patch as well, hopefully there's no rush to commit it..
Comment #12
tim.plunkettLet's do this, as I definitely want your input.
Comment #13
amateescu commentedI've been staring for a while at
\Drupal\layout_builder\InlineBlockEntityOperations::handleEntityDelete()and all its possible code paths, and I can't find what would trigger a call toEntityContext::fromEntity($entity)in there..Is there some other part of the code that I should also be looking at? :)
Comment #14
amateescu commentedOops, didn't want to un-assign, I'm still looking into it.
Comment #16
alexpottThis looks very reasonable - but perhaps a code comment might be a good idea - so people know when we might use the passed in entity instead of the unchanged one.
Comment #18
jhedstromSetting to NW for the code comment mentioned in #16.
Comment #23
larowlanTagging to get some eyes to add the comment
Comment #24
yogeshmpawarUpdated patch with reroll diff & addressed #16
Comment #25
yogeshmpawarComment #28
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #29
rishabh vishwakarma commentedAdding patch against 10.0.1
Comment #30
ameymudras commentedDid a brief code review and the following comment doesn't make sense to me, I think we should reword it. Otherwise, the code looks good
// We might use the passed entity instead of the unchanged one.Comment #31
sahil.goyal commentedMade change to the comment as per #30 so the comment is now quite relevant what it supposed to do.
Comment #32
sahil.goyal commentedComment #33
smustgrave commentedAttempted to replicate this by running the code in the issue summary and I don't get any error in 10.1
Can someone please confirm if it's still an issue and update the issue summary with additional steps
Thanks!
Comment #34
tim.plunkettI think the codepath described by the test case (introduced in #7) was at one time relevant to how Layout Builder was working, but is not reproducible anymore in core. And I can't think of a reason why you'd need to do it in custom code either.
Comment #35
amateescu commentedThere's still a reference in code to this issue in
\Drupal\layout_builder\InlineBlockEntityOperations::handleEntityDelete(), let's see if callingisLayoutCompatibleEntity()is possible now.Comment #37
amateescu commentedOpened a MR, let's see how it goes.
Comment #38
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue.
While you are making the above changes, we recommend that you convert this patch to a merge request. Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)
Comment #39
amateescu commentedHiding the patches because the MR seems to work well :)
Comment #40
smustgrave commentedUpdated title and solution to mention this seems to be cleaning up a todo and use isLayoutCompatibleEntity().
Comment #41
alexpottAdded a question the MR.
Comment #42
smustgrave commentedMoving to NW for someone to test that proposal.
Comment #44
brandonlira commentedHi all,
I removed the isLayoutCompatibleEntity($entity) check before calling removeByLayoutEntity($entity), as suggested.
Tests performed:
PHPUnit: All tests passed successfully, with no errors found. Only pre-existing skipped tests remained unchanged.
The change has been committed and submitted in the Merge Request. Awaiting feedback for any necessary adjustments!
Thank you!
Comment #45
smustgrave commentedMR is 1800+ commits back.
Comment #46
brandonlira commentedHi @smustgrave
I have successfully rebased the branch with the latest changes from 11.x. The MR !7106 is now up to date, and the previous changes remain intact.
Additionally, I noticed that one test failed, but it does not appear to be related to the changes made in this MR.
Please let me know if you need any additional adjustments.
Thanks!
Comment #47
brandonlira commentedComment #48
smustgrave commentedSo reading the issue summary and title
Still seems to be needed.
Comment #49
brandonlira commentedHi @smustgrave,
Apologies if I might be misunderstanding something here, but I just want to clarify the intent behind this change to ensure I'm following the best approach. I'm still getting started with contributing to Drupal, and I really appreciate your guidance.
The issue summary suggests that
handleEntityDelete()should be updated to useisLayoutCompatibleEntity(), but after reviewing the implementation, I noticed thatremoveByLayoutEntity($entity)does not fail if the entity is not layout-compatible. Instead, it simply attempts to clean upinline_block_usage, settinglayout_entity_idandlayout_entity_typeto NULL if applicable. If no matching records exist, nothing happens, which makes me wonder if the extra check is truly necessary.I just want to make sure I'm not missing something here:
isLayoutCompatibleEntity()?removeByLayoutEntity()directly could cause unintended side effects?If the check is needed for a reason I’m not seeing, I’ll be happy to update it accordingly. Otherwise, removing it might help simplify the logic while still ensuring the cleanup happens.
Again, thanks for your patience and feedback—I really appreciate learning from this process!
Comment #50
smustgrave commentedNo worries. So might help to look at the reference issue this was created from.
Not a layout builder expert to say what’s needed or not but the summary needs to match the MR. Helps committers quickly understand a ticket
If it’s determined nothing is needed then the summary could include your findings and just a simple solution of remove the todo
Comment #51
smustgrave commentedCan put back into review for more eyes but before RTBC summary will have to match
Comment #52
godotislateComment #53
smustgrave commentedThanks. then believe this ticket may be ready.
Comment #54
xjmThanks @smustgrave and @brandonlira for digging into the issue. The issue summary was indeed out of date, as the scope of this issue changed when old code was removed. See #34 and #35.
Since a field subsystem maintainer created this MR, that gives me confidence that this
@todois invalid and should be removed.Saving issue credits.
Comment #59
xjmSince it's a non-disruptive cleanup of bad, actually wrong inline docs, I backported it all the way to 10.5.x. (Branch parity for things like tests and docs is sort of a gray area for maintenance minors; it's not officially listed but for some things we can keep parity.)
Thanks everyone!