Support from Acquia helps fund testing for Drupal Acquia logo

Comments

slashrsm created an issue. See original summary.

bojanz’s picture

Priority: Normal » Major

This needs to be our biggest IEF priority, otherwise we'll need to keep adding band-aids for bugs the D7 version doesn't have.

tedbow’s picture

I just taken a good look at http://cgit.drupalcode.org/inline_entity_form/diff/?id=a754ba7
Which the commit for the referenced issue.

It looks to me like most if not all of the logic for that patch is already in 8.x-1.x.

tedbow’s picture

Status: Active » Needs review
FileSize
10.84 KB

Ok uploading a patch that fixes some remaining submissions.

I wasn't sure if I should post it here or #2626970: Add testcase for nested inline entity form

This patch does get all of those test passing up to this point on the issue:
https://www.drupal.org/node/2626970#comment-10826306

I have upload this patch I will add another comment explaining some of the changes

tedbow’s picture

+++ b/src/Element/InlineEntityForm.php
@@ -256,4 +258,52 @@ class InlineEntityForm extends RenderElement {
+  public static function addSubmitCallbacks(&$element) {
+    $element['#submit'] = [
+      ['\Drupal\inline_entity_form\Element\InlineEntityForm', 'triggerIefSubmit'],
+      ['\Drupal\inline_entity_form\Element\InlineEntityForm', 'closeForm'],
+    ];
+    $element['#ief_trigger']  = TRUE;
+  }
+

Create addSubmitCallBacks because this same two function were being added in multiple places in this manner.

I also added #ief_trigger as a way to know which elements should trigger IEF saves so that isSubmitRelevant could be much simplier.

+++ b/inline_entity_form.module
@@ -258,16 +239,6 @@ function inline_entity_form_open_row_form($form, FormStateInterface $form_state)
-function inline_entity_form_close_child_forms($form, &$form_state) {

Moved this function to static function on \Drupal\inline_entity_form\Element\InlineEntityForm

This could probably be done with more functions to remove code from .module file

+++ b/inline_entity_form.module
@@ -530,3 +501,14 @@ function inline_entity_form_pre_render_add_fieldset_markup($form) {
+/**
+ * Implements hook_form_alter().
+ */
+function inline_entity_form_form_alter(&$form, FormStateInterface &$form_state, $form_id) {
+  if ($form_state->get('inline_entity_form')) {
+    InlineEntityForm::attachMainSubmit($form);
+  }
+
+}
diff --git a/src/Element/InlineEntityForm.php b/src/Element/InlineEntityForm.php

This was not ported from D7 before. This ensures that main submit button gets the IEF callbacks.

Relying on AJAX callbacks to do this doesn't seem to work.

+++ b/src/Element/InlineEntityForm.php
@@ -153,6 +153,7 @@ class InlineEntityForm extends RenderElement {
+      $complete_form['submit']['#ief_trigger']  = TRUE;

Ensuring that parent form buttons are marked as IEF triggers.

+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php
@@ -411,25 +411,8 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
   protected function isSubmitRelevant(array $form, FormStateInterface $form_state) {
-    $field_name = $this->fieldDefinition->getName();
-    $field_parents = array_slice(array_merge($form['#parents'], [$field_name, 'form']), 0, -1);
-
     $trigger = $form_state->getTriggeringElement();
-    if (isset($trigger['#limit_validation_errors']) && $trigger['#limit_validation_errors'] !== FALSE) {
-      $relevant_sections = array_filter(
-        $trigger['#limit_validation_errors'],
-        function ($item) use ($field_parents) {
-          $union = $field_parents + $item;
-          return $union == max(count($item), count($field_parents));
-        }
-      );
-
-      if (empty($relevant_sections)) {
-        return FALSE;
-      }
-    }
-
-    return TRUE;
+    return !empty($trigger['#ief_trigger']);

Because of #ief_trigger we can remove this logic and just check if it is a trigger.

+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php
@@ -611,19 +612,24 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF
-      foreach ($values as $delta => &$item) {
-        /** @var \Drupal\Core\Entity\EntityInterface $entity */
-        $entity = $item['entity'];
-        if (!empty($item['needs_save'])) {
-          $entity->save();
-        }
-        if (!empty($item['delete'])) {
-          $entity->delete();
-          unset($items[$delta]);
+      $trigger = $form_state->getTriggeringElement();
+
+      if (!empty($trigger['#ief_submit_all'])) {
+        foreach ($values as $delta => &$item) {
+          /** @var \Drupal\Core\Entity\EntityInterface $entity */
+          $entity = $item['entity'];
+          if (!empty($item['needs_save'])) {
+            $entity->save();
+          }
+          if (!empty($item['delete'])) {
+            $entity->delete();
+            unset($items[$delta]);
+          }

We should not actually be doing the saves or deletes until the main parent submit button is submitted(checked via #ief_submit_all)

This from my understanding that entities should only be saved with the main form.

mansspams’s picture

This is great! Golden star!

slashrsm’s picture

This looks great. Just few cosmetic fixes:
- functions that were added to \Drupal\inline_entity_form\Element\InlineEntityForm are widget-specific logic and should live in widget class as such.
- Entirely removed isSubmitRelevant() and moved the check to the calling function.

Will test this patch manually a bit more, but I think we should be pretty close.

Thank you!

slashrsm’s picture

Found a bug... Steps to reproduce:
- enabled inline_entity_form_test
- make reference fields on ief_test_nested1 and ief_test_nested2 content types non-required
- navigate to /node/add/ief_test_nested1 and create all 3 levels
- save parent entity
- edit entity that was just created
- open all nested IEFs
- change something on the last level
- close (update) all IEF forms
- save parent entity
- navigate back to edit page
- open all nested IEF forms
- Expected result: changes on last level were saved and are now visible
- Actual result: Changes on last level were not saved at all

However, without this patch entity on last level won't save at all (when creating them). Taking that into consideration I think it is ok to tackle this bug in a follow-up (with test coverage and everything).

I think it makes sense to get this in asap as:
- it fixes existing bugs,
- allows us to commit #2626970: Add testcase for nested inline entity form too, which adds even more test coverage.

tedbow’s picture

Ok here is another patch that makes a small change in \Drupal\inline_entity_form\Form\EntityInlineForm::entityFormValidate to make sure validation is only run on an entityform if the submission was trigger by the current IEF element.

This will allow one of the "required" tests in #2626970: Add testcase for nested inline entity form that is currently commented out to pass.

It also fixes part of #2649710: Required nested IEF forms don't work it allows fields that are required to work but only if you submit the forms via ajax NOT leave them open.

Status: Needs review » Needs work

The last submitted patch, 9: ief-forward_port_submission-2612720-9.patch, failed testing.

tedbow’s picture

Status: Needs work » Needs review
FileSize
13.47 KB
2.52 KB

Ok my 8.x-1.x was behind locally

The interdiff is still against #7

  • slashrsm committed 4380d1d on 8.x-1.x authored by tedbow
    Issue #2612720 by tedbow, slashrsm: Forward port submission improvements...
slashrsm’s picture

Issue summary: View changes
Status: Needs review » Fixed

I went ahead and committed #7. Patches #9 and #11 belong to another issue with a different scope. They were uploaded here simply because they depended on this.

Getting this in also allowed me to commit #2626970: Add testcase for nested inline entity form, which adds valuable tests. All that will help us going forward. Anyone feel free to re-open if problems with the patch are revealed.

Thank you everyone!

Will re-upload #11 to #2649710: Required nested IEF forms don't work so we can continue there.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.