To recreate this issue:
- Add two fields to a node, 1 Entity Ref for products, one a basic text field that is required
- Add a new node of this type and in the add form, leave the required text field blank
- Click the "Add new product" button and fill out the product form
- Now click the parent "Save" button, not "Create product". This will leave the product form open
- You should get a required text field validation error
- Click "Save" again while leaving the required field blank
- You should get another required text field validation error
- Now fill in the required field and click "Save" again
- You either just created 3 identical products, or you will get a PDO error for duplicate product SKUs
This is caused by the inline_entity_form_process_entity_form() being called before the required text field has failed validation. Each time inline_entity_form_process_entity_form() is called on Save, you are added a new entity to the $form_state['inline_entity_form'][$ief_id]['entities'] array.
To fix this problem, I've added an "open" flag set to true on inline_entity_form_open_form() and false on inline_entity_form_close_form() for the multi-entity widget. Then inline_entity_form_process_entity_form() check to see if the main parent "Save" button was the triggering element when the form was open. It now forces you to click "Create product" BEFORE you can click "Save" on the multi widget. For the single IEF widget, it checks to make sure there are no entities on the $form_state['inline_entity_form'][$ief_id]['entities'] array before it adds one.
Patch to follow.
Comments
Comment #1
bendiy commentedSee attached patch.
Comment #2
tonylegrone commentedHi Bendiy,
I have applied the patch, but it doesn't seem to be having any effect. From what I can tell, the ['open'] flag is not yet set when the script tests for it on line 873 of inline_entity_form.module and the duplicate still runs.
Comment #3
bendiy commented@tonylegrone
The inline_entity_form_open_form() function should be called when you click the "Add new product" button. That function sets the 'open' flag. Can you verify that it's getting called?
I'm using the "Multiple value" widget. I also have #2032649: Rework inline form submission applied to my code and a few other patches.
Maybe try clearing your cache?
Comment #4
tonylegrone commentedI didn't have to click "Add new product" because I have "Allow users to add existing products" disabled for the IEF field. I'll have to do some more testing on that.
Comment #5
bendiy commented@tonylegrone
That problem was caused by using the single IEF widget, which doesn't have an "Add new product" button, the form is open as soon as the page loads.
I've tweaked the patch to add support/fix for the Single widget as well. Please give this patch a try. It should fix this issue for you.
Comment #6
bendiy commentedComment #7
tonylegrone commentedThe first test still didn't work. I looked at the logic for the open flag on 872 and I think it was backwards. After fixing that, I discovered the t() was written as $t() on line 878.
I have updated the patch to fix those lines and it looks like it's working 100%.
Comment #8
bendiy commentedI just noticed the $t problem, should also be fixed in the attached patch.
I believe the $open logic was correct. You will want $open to default to FALSE when this is for a "Single Value" widget and when the #op is 'edit' so the whole validation error code block will be skipped. That block of code should only be for "Multiple Values" widget. If you default that to TRUE, you will get a validation error every time the parent "Save" button is clicked. Are you sure you're on the "Multiple Values" widget and not the "Single Value" widget?
I also had the patch for this issue included in there: #1839676: Add hook_inline_entity_form_settings_alter()
I've removed it.
Comment #8.0
bendiy commentedAdd info about single widget
Comment #9
checker commentedI tested patch #8 and it looks good with single value widget.
Comment #10
bojanz commentedMarking as duplicate of #2032649: Rework inline form submission.
Please test / reroll the patch there.