Sorry if I'm posting this issue in the wrong place, but I was only able to fix the problem on Core level as you can see it in the patch.
Reproduce
- Install the Paragraphs with composer and enable it.
- Install Inline Entity Form module with composer and enable it.
- Apply the patch from https://www.drupal.org/project/inline_entity_form/issues/3015323, patch: https://www.drupal.org/files/issues/2018-11-26/3015323-3.patch
- Enable the core Workflows module.
- Create a basic Paragraph type (Paragraph Test).
- Create a new content type (Bar) with a Paragraph field (Paragraph field) that uses the previously created paragraph type (Paragraph Test) set it not to be required.
- Create a new content type (Foo) with a Reference field (Inline form), referencing the previously created content type (Bar).
- Choose the 'Inline Entity Form - Complex' widget for the field (Inline form), in the Form display page.
- Create a new workflow (Moderation) apply it to the previously created content type (Foo).
Steps to reproduce:
- Add a new content for the Bar content type do not add a paragraph yet
- Add a new content for the Foo content type and load the existing Bar entity into the Inline form field
- Save the entity
- Go back to the Foo entity's edit page and open the Inline form field's referenced Bar entity with the Edit button
- Click on the Add new paragraph button in the Paragraph field named field
- Nothing should happen which is the sign that the problem exists
- Check the Network tab in the Browser's developer tool and you will see the Internal Server error message.
Expected behavior
The expected behavior is that the Add new paragraph button adds the paragraph fields to the form.
Proposed solution
I've created a patch, where the EntityTypeInfo.php's entityPrepareForm method is "fixed".
The problem was that the $entity and the $form_object->getEntity() objects were not the same in case when I used the Inline Entity Form.
And the method only checked if the $form_object is moderated entity form or not, but didn't check if the $entity itself is a moderated entity or not. I also added the $form_object->getEntity() === $entity so this way only the correct entity will get the new revision.
That is the point where I'm uncertain about that the problem lays here at the Content moderation module or in the Inline Entity Form, because the $entity comes from the latter one. I think the content moderation module should check if the received $entity is moderated and belongs to the current form object or not. This way the default behavior persists and the Inline Entity Form incompatibility is fixed, because the module won't try to create a new revision for the wrong entity and won't overwrite the entity in the $form_object.
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | 3072952-6.patch | 1.01 KB | ershov.andrey |
| content-moderation-state-inline-entity-form-bug-1.patch | 1.01 KB | Kova101 |
Comments
Comment #2
Kova101 commentedComment #3
sam152 commentedRe: tags.
You haven't really described in the steps to reproduce where content moderation is involved. Are you saying if some content type Foo has an IEF to some content type Bar, which has a content moderation workflow applied, there is an error?
I think without the proper concept of nested entity forms in core, this will be quite difficult to test with core itself.
Re: the patch
Isn't this already checked in
isModeratedEntityEditForm?Comment #4
Kova101 commentedHello Sam152,
Thank you for the answer. I've updated the description to contain more detailed steps.
You are right the
isModeratedEntityEditFormmethod checksisModeratedEntity.The main problem we faced during a project is that a
Fooentity has content moderation applied for it and also has aIEFthat points to aBarentity that has Paragraph fields and the Add new or Remove functions do not work within the IEF.I've been able to fix the problem in the
EntityTypeInfo'sentityPrepareFormmethod with the attached solution. The problem I've found is that the IEF calls thehook_entity_prepare_formand the $entity that passed to it is the entity that is in the IEF so theBarentity, but the $form_state is for the whole form, so basically for theFooentity. And theEntityTypeInfo'sentityPrepareFormsees that theFooentity is moderated and creates a new revision for it from the $entity which in this case "incorrectly" is theBarentity.This results in overriding the form object's enity from
FootoBar, which ends up causing errors because of different fields.I had a lot of trouble to decide where to put this issue, because I think it should be in the IEF module, but I could not resolve the problem at that level, because manipulating the $form_state there is not a good practice in my opinion. So I've decided to put it here with a basic patch, hoping someone could help me with this situation.
I hope it is more understandable now. If you have questions then please do not hesitate to ask it. Or if you have some advice or solution I would appreciate it.
Comment #6
ershov.andrey commentedPatch updated for Drupal 8.8.1 version
Comment #7
geek-merlinIEF Comaintainer here. @Kova101 #5: Thanks a lot for your clarifiations!
>The problem I've found is that the IEF calls the hook_entity_prepare_form and the $entity that passed to it is the entity that is in the IEF so the Bar entity, but the $form_state is for the whole form, so basically for the Foo entity.
Are you sure? Can you provide a backtrace for this? Background: I stumbled upon this when i realized that neither IEF nor paragraphs currently invoke that hook, and validated via grep.
(EDIT: Do you mean hook_entity_prepare_form or EntityTypeInfo::entityPrepareForm that is mentioned in the IS?)
Another thing, whatever you see passing not-matching form state, the answer is likely to be SubformState.