Problem/Motivation

Coming from #2721349: Nested inline entities must be saved in "inside-out" order, i noted that we make quite a throughout the code to track iIEF entities in $form_state, to finally save them in \Drupal\inline_entity_form\WidgetSubmit::doSubmit. I suppose all that came from D7.

Otoh, looking into \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem, in D8, it can well do the job for us in preSave:


  /**
   * Determines whether the item holds an unsaved entity.
   *
   * This is notably used for "autocreate" widgets, and more generally to
   * support referencing freshly created entities (they will get saved
   * automatically as the hosting entity gets saved).
   *
   * @return bool
   *   TRUE if the item holds an unsaved entity.
   */
  public function hasNewEntity() {
    return !$this->isEmpty() && $this->target_id === NULL && $this->entity->isNew();
  }

  public function preSave() {
    if ($this->hasNewEntity()) {
      // Save the entity if it has not already been saved by some other code.
      if ($this->entity->isNew()) {
        $this->entity->save();
      }
      // Make sure the parent knows we are updating this property so it can
      // react properly.
      $this->target_id = $this->entity->id();
    }
    if (!$this->isEmpty() && $this->target_id === NULL) {
      $this->target_id = $this->entity->id();
    }
  }

Proposed resolution

Remove our $entity->save() logic and let the field do the job. Benefits:
- Largely reduced complexity on our side.
- Works also for special EntityReferenceItem implementations

Update: This works in principle, but only for new entities.

Remaining tasks

- Figure out how to fix the above.

User interface changes

API changes

Data model changes

Command icon 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

geek-merlin created an issue. See original summary.

geek-merlin’s picture

Title: Leverate Entity API to save IRF entities » Leverate Entity API to save IEF entities
geek-merlin’s picture

Title: Leverate Entity API to save IEF entities » Leverate EntityReference::preSave to save IEF entities

Interesting:
- In patch #2966933-11: Complex widget doesn't yield automatic pathauto aliases, the WidgetSubmit::doSubmit $entity->save() logic is disabled for pathauto-needing entities, which is reported to fix that issue, but does not break IEF.

I wonder what happens if we remove that $entity->save completely.

geek-merlin’s picture

Removed our saving logic.

Some entity saving tests seem to still work, while others fail.

For example, ComplexSimpleWidgetTest.testSimpleInComplex creates some nodes and passes.

Interesting.

Checking some failing tests, the pattern may be that creating entities works, while updating fails.

geek-merlin’s picture

Issue summary: View changes

OK, now i grok that core logic:
- It saves unsaved entities without ID. According to above test results, this really obsoletes our $form_state storage for creating new entities.
- It does not save changed entities with ID. Until maybe core does this one day, we'd have to do this ourselves :-/. Not sure how easy that is, compared to the current approach.

aaronbauman’s picture

Title: Leverate EntityReference::preSave to save IEF entities » Leverage EntityReference::preSave to save IEF entities

fixed typo in title

geek-merlin’s picture

OK, so to sum up. i tried what can be done with FieldType/TypedData, but no low hanging success. Still thinking, as this would imho be gold standard.

(If referenced entities are auto-saved just before the entity itself, this is proof that saving always happens in the right order.)

geek-merlin’s picture

geek-merlin’s picture

We'd need that upstream.

geek-merlin’s picture

The current approach uses hook_entity_presave to emulate field item autosave.
Some tests are failing, so this may or may not work out.

geek-merlin’s picture

Pooja Ganjage made their first commit to this issue’s fork.

Pooja Ganjage’s picture

Status: Active » Needs review
geek-merlin’s picture

Status: Needs review » Postponed

This turned out much mor complicated than thought, so the other approaches had been preferrable for now.

I still believe that this should be the way to go at some point in the future.