diff --git a/src/Element/InlineEntityForm.php b/src/Element/InlineEntityForm.php index e109ab5..4df4bd0 100644 --- a/src/Element/InlineEntityForm.php +++ b/src/Element/InlineEntityForm.php @@ -3,6 +3,8 @@ namespace Drupal\inline_entity_form\Element; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\RevisionableEntityBundleInterface; +use Drupal\Core\Entity\RevisionLogInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\Core\Render\Element\RenderElement; @@ -97,6 +99,7 @@ class InlineEntityForm extends RenderElement { throw new \InvalidArgumentException('The inline_entity_form #default_value property must be an entity object.'); } + $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_form['#entity_type']); if (empty($entity_form['#ief_id'])) { $entity_form['#ief_id'] = \Drupal::service('uuid')->generate(); } @@ -106,7 +109,6 @@ class InlineEntityForm extends RenderElement { } else { // This is an add operation, create a new entity. - $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_form['#entity_type']); $storage = \Drupal::entityTypeManager()->getStorage($entity_form['#entity_type']); $values = []; if ($langcode_key = $entity_type->getKey('langcode')) { @@ -132,6 +134,23 @@ class InlineEntityForm extends RenderElement { $entity_form['#entity'] = TranslationHelper::prepareEntity($entity_form['#entity'], $form_state); $entity_form['#translating'] = TranslationHelper::isTranslating($form_state) && $entity_form['#entity']->isTranslatable(); + // Set revision property if the bundle is configured to. + // @see \Drupal\Core\Entity\ContentEntityForm::addRevisionableFormFields + if ( + $entity_type->isRevisionable() + && ($bundle_entity_type = $entity_form['#entity']->getEntityType()->getBundleEntityType()) + && ($bundle_entity = \Drupal::entityTypeManager()->getStorage($bundle_entity_type)->load($entity_form['#entity']->bundle())) + && $bundle_entity instanceof RevisionableEntityBundleInterface + ) { + $new_revision = $bundle_entity->shouldCreateNewRevision(); + $entity_form['#entity']->setNewRevision($new_revision); + // @see \Drupal\Core\Entity\ContentEntityForm::buildEntity + if ($new_revision && $entity_form['#entity'] instanceof RevisionLogInterface) { + $entity_form['#entity']->setRevisionUserId(\Drupal::currentUser()->id()); + $entity_form['#entity']->setRevisionCreationTime(\Drupal::time()->getRequestTime()); + } + } + $inline_form_handler = static::getInlineFormHandler($entity_form['#entity_type']); $entity_form = $inline_form_handler->entityForm($entity_form, $form_state); // The form element can't rely on inline_entity_form_form_alter() calling @@ -166,7 +185,7 @@ class InlineEntityForm extends RenderElement { $inline_form_handler = static::getInlineFormHandler($entity_form['#entity_type']); $inline_form_handler->entityFormSubmit($entity_form, $form_state); if ($entity_form['#save_entity']) { - $inline_form_handler->save($entity_form['#entity'], $form_state); + $inline_form_handler->save($entity_form['#entity']); } } diff --git a/src/Form/EntityInlineForm.php b/src/Form/EntityInlineForm.php index 39c167c..9bd26eb 100644 --- a/src/Form/EntityInlineForm.php +++ b/src/Form/EntityInlineForm.php @@ -2,20 +2,18 @@ namespace Drupal\inline_entity_form\Form; +use Drupal\Component\Utility\DiffArray; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\Entity\EntityFormDisplay; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Entity\RevisionableInterface; -use Drupal\Core\Entity\RevisionLogInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\inline_entity_form\InlineFormInterface; -use Drupal\node\NodeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -258,21 +256,25 @@ class EntityInlineForm implements InlineFormInterface { $form_state->cleanValues(); /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $entity_form['#entity']; + $original_values = $entity->toArray(); $this->buildEntity($entity_form, $entity, $form_state); + $current_values = $entity->toArray(); + // Mark this entity for saving only if its values have changed. + // The entity changed flag that we add here is extracted in + // InlineEntityFormBase::submitSaveEntity and triggers saving in + // WidgetSubmit::doSubmit. + // Saving is not done in InlineEntityForm::submitEntityForm (it looks like + // the check of $entity_form['#save_entity'] is dead code). + // @todo Use EntityChangedAPI once this lands in + // @see https://www.drupal.org/project/drupal/issues/2862574 + $entity_changed = (bool) DiffArray::diffAssocRecursive($original_values, $current_values); + $entity->_inline_entity_form_entity_changed = $entity_changed; } /** * {@inheritdoc} */ - public function save(EntityInterface $entity, FormStateInterface $form_state) { - if ($this->shouldSaveNewRevision($entity, $form_state)) { - $entity->setNewRevision(); - if ($entity instanceof RevisionLogInterface) { - // If a new revision is created, save the current user as revision author. - $entity->setRevisionUserId(\Drupal::currentUser()->id()); - $entity->setRevisionCreationTime(REQUEST_TIME); - } - } + public function save(EntityInterface $entity) { $entity->save(); } @@ -353,33 +355,4 @@ class EntityInlineForm implements InlineFormInterface { return EntityFormDisplay::collectRenderDisplay($entity, $form_mode); } - /** - * Determines whether we should save a new revision. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The form state. - * - * @return bool - */ - protected function shouldSaveNewRevision(EntityInterface $entity, FormStateInterface $form_state) { - $new_revision = FALSE; - if ($entity instanceof RevisionableInterface && $entity->getEntityType()->isRevisionable()) { - if ($entity->isNewRevision()) { - $new_revision = TRUE; - } - - // Most of the time we don't know yet if the host entity is going to be - // saved as a new revision using RevisionableInterface::isNewRevision(). - // Most entity types (at least nodes) however use a boolean property named - // "revision" to indicate whether a new revision should be saved. Use that - // property. - elseif ($form_state->getValue('revision')) { - $new_revision = TRUE; - } - } - return $new_revision; - } - } diff --git a/src/Form/NodeInlineForm.php b/src/Form/NodeInlineForm.php index 58ad438..4f6c377 100644 --- a/src/Form/NodeInlineForm.php +++ b/src/Form/NodeInlineForm.php @@ -2,10 +2,8 @@ namespace Drupal\inline_entity_form\Form; -use Drupal\Core\Entity\RevisionableInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\node\NodeInterface; /** * Node inline form handler. diff --git a/src/InlineFormInterface.php b/src/InlineFormInterface.php index 4c9beb2..f7b0b2a 100644 --- a/src/InlineFormInterface.php +++ b/src/InlineFormInterface.php @@ -125,13 +125,11 @@ interface InlineFormInterface extends EntityHandlerInterface { * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The form state of the parent form. * * @return int * Either SAVED_NEW or SAVED_UPDATED, depending on the operation performed. */ - public function save(EntityInterface $entity, FormStateInterface $form_state); + public function save(EntityInterface $entity); /** * Delete permanently saved entities. diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php index 5598be4..bafcbee 100644 --- a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php +++ b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php @@ -502,7 +502,8 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto $delta = $entity_form['#ief_row_delta']; $entities = $form_state->get(['inline_entity_form', $ief_id, 'entities']); $entities[$delta]['entity'] = $entity; - $entities[$delta]['needs_save'] = TRUE; + // @see \Drupal\inline_entity_form\Form\EntityInlineForm::entityFormSubmit + $entities[$delta]['needs_save'] = !empty($entity->_inline_entity_form_entity_changed); $form_state->set(['inline_entity_form', $ief_id, 'entities'], $entities); } } diff --git a/src/WidgetSubmit.php b/src/WidgetSubmit.php index 5c5e8da..98921a4 100644 --- a/src/WidgetSubmit.php +++ b/src/WidgetSubmit.php @@ -2,11 +2,8 @@ namespace Drupal\inline_entity_form; -use Drupal\Core\Entity\RevisionableInterface; -use Drupal\Core\Entity\RevisionLogInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\inline_entity_form\Element\InlineEntityForm; -use Drupal\node\NodeInterface; /** * Performs widget submission. @@ -49,7 +46,7 @@ class WidgetSubmit { /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $entity_item['entity']; $handler = InlineEntityForm::getInlineFormHandler($entity->getEntityTypeId()); - $handler->save($entity, $form_state); + $handler->save($entity); $widget_state['entities'][$delta]['needs_save'] = FALSE; } }