diff --git a/config/schema/inline_entity_form.schema.yml b/config/schema/inline_entity_form.schema.yml index 0637fa8..e6c1a6f 100644 --- a/config/schema/inline_entity_form.schema.yml +++ b/config/schema/inline_entity_form.schema.yml @@ -22,6 +22,9 @@ field.widget.settings.inline_entity_form_simple: match_operator: type: string label: "Match operator" + display_mode: + type: string + label: "Display mode" field.widget.settings.inline_entity_form_complex: type: mapping @@ -45,3 +48,6 @@ field.widget.settings.inline_entity_form_complex: match_operator: type: string label: "Match operator" + display_mode: + type: string + label: "Display mode" diff --git a/src/Element/InlineEntityForm.php b/src/Element/InlineEntityForm.php index 8537089..8562ef3 100644 --- a/src/Element/InlineEntityForm.php +++ b/src/Element/InlineEntityForm.php @@ -35,6 +35,9 @@ class InlineEntityForm extends RenderElement { '#entity' => NULL, '#entity_type' => NULL, '#bundle' => NULL, + // Instance of \Drupal\Core\Entity\Display\EntityFormDisplayInterface. + // The entity form display that is used to display the entity. + '#ief_display_mode' => NULL, '#op' => 'add', // Will hide entity form's own actions if set to FALSE. '#display_actions' => FALSE, @@ -93,6 +96,10 @@ class InlineEntityForm extends RenderElement { return; } + if (empty($element['#entity_form_display'])) { + $element['#entity_form_display'] = $ief_handler->getEntityFormDisplay(); + } + // If entity object is not there we're displaying the add form. We need to // create a new entity to be used with it. if (empty($element['#entity'])) { diff --git a/src/Form/EntityInlineForm.php b/src/Form/EntityInlineForm.php index 321dbed..95a45f1 100644 --- a/src/Form/EntityInlineForm.php +++ b/src/Form/EntityInlineForm.php @@ -7,6 +7,7 @@ namespace Drupal\inline_entity_form\Form; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\Display\EntityFormDisplayInterface; use Drupal\Core\Entity\EntityFormInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; @@ -138,13 +139,30 @@ class EntityInlineForm implements InlineFormInterface { /** * {@inheritdoc} */ + public static function getOperation($entity_form, $default_operation = 'default') { + $display_mode = $entity_form['#ief_display_mode']; + $display_mode_name = ($display_mode instanceof EntityFormDisplayInterface) ? $display_mode->getMode() : $default_operation; + return empty($entity_form['#entity']->getEntityType()->getFormClass($display_mode_name)) ? $default_operation : $display_mode_name; + } + + /** + * {@inheritdoc} + */ public function entityForm($entity_form, FormStateInterface $form_state) { - $operation = 'default'; + $display_mode = $entity_form['#ief_display_mode']; + $display_mode_name = ($display_mode instanceof EntityFormDisplayInterface) ? $display_mode->getMode() : 'default'; + $operation = static::getOperation($entity_form); + $controller = $this->entityManager->getFormObject($entity_form['#entity']->getEntityTypeId(), $operation); $controller->setEntity($entity_form['#entity']); $child_form_state = $this->buildChildFormState($controller, $form_state, $entity_form['#entity'], $operation); - $entity_form = $controller->buildForm($entity_form, $child_form_state); + if ($operation === $display_mode_name) { + $entity_form = $controller->buildForm($entity_form, $child_form_state); + } + else { + $entity_form['#ief_display_mode']->buildForm($entity_form['#entity'], $entity_form, $child_form_state); + } if (!$entity_form['#display_actions']) { unset($entity_form['actions']); @@ -187,7 +205,7 @@ class EntityInlineForm implements InlineFormInterface { if ($validate) { /** @var \Drupal\Core\Entity\EntityInterface $entity */ $entity = $entity_form['#entity']; - $operation = 'default'; + $operation = static::getOperation($entity_form); $controller = \Drupal::entityManager() ->getFormObject($entity->getEntityTypeId(), $operation); @@ -226,7 +244,7 @@ class EntityInlineForm implements InlineFormInterface { public static function entityFormSubmit(&$entity_form, FormStateInterface $form_state) { /** @var \Drupal\Core\Entity\EntityInterface $entity */ $entity = $entity_form['#entity']; - $operation = 'default'; + $operation = static::getOperation($entity_form); $controller = \Drupal::entityManager()->getFormObject($entity->getEntityTypeId(), $operation); $controller->setEntity($entity); @@ -349,4 +367,27 @@ class EntityInlineForm implements InlineFormInterface { } } + /** + * {@inheritdoc} + */ + public function getEntityFormDisplays() { + return $this->entityManager + ->getStorage('entity_form_display') + ->loadByProperties([ + 'targetEntityType' => $this->entityTypeId() + ]); + } + + /** + * {@inheritdoc} + */ + public function getEntityFormDisplay($display_mode_name = 'default') { + $display_modes = $this->getEntityFormDisplays(); + $display_mode = current($display_modes); + if (isset($display_modes[$display_mode_name])) { + $display_mode = $display_modes[$display_mode_name]; + } + return $display_mode; + } + } diff --git a/src/InlineFormInterface.php b/src/InlineFormInterface.php index ab39e3c..6202e90 100644 --- a/src/InlineFormInterface.php +++ b/src/InlineFormInterface.php @@ -78,6 +78,33 @@ interface InlineFormInterface extends EntityHandlerInterface { public function entityTypeId(); /** + * Returns the id of entity type managed by this handler. + * + * @return string + * The [entity form] operation name + */ + public static function getOperation($entity_form, $default_operation = 'default'); + + /** + * Returns an array of entity form display entities to be used as options in + * the widget settings form. + * + * @return \Drupal\Core\Entity\Display\EntityFormDisplayInterface[] + */ + public function getEntityFormDisplays(); + + /** + * Returns the entity form display entity selected in the settings widget. + * If the display mode doesn't exist in the available modes list then return + * the first mode in the list. + * + * @param string $display_mode_name + * + * @return \Drupal\Core\Entity\Display\EntityFormDisplayInterface + */ + public function getEntityFormDisplay($display_mode_name = 'default'); + + /** * Returns the entity form to be shown through the IEF widget. * * When adding data to $form_state it should be noted that there can be diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php index 4cc2db4..2bedf12 100644 --- a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php +++ b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php @@ -7,6 +7,7 @@ namespace Drupal\inline_entity_form\Plugin\Field\FieldWidget; +use Drupal\Core\Entity\Display\EntityFormDisplayInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Field\FieldDefinitionInterface; @@ -152,6 +153,7 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto 'override_labels' => FALSE, 'label_singular' => '', 'label_plural' => '', + 'display_mode' => NULL, ]; } @@ -187,6 +189,18 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto ), ); + $entity_form_displays = $this->iefHandler->getEntityFormDisplays(); + $element['display_mode'] = array( + '#type' => 'select', + '#title' => $this->t('Display mode'), + '#default_value' => $this->getSetting('display_mode') + ? $this->getSetting('display_mode') + : key($entity_form_displays), + '#options' => array_map(function(EntityFormDisplayInterface $item) { + return $item->getMode(); + },$entity_form_displays) + ); + return $element; } @@ -288,6 +302,8 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto // access to those in static callbacks (#process, ...) so let's add // them here. '#ief_labels' => $this->labels(), + // Pass the display mode to the entity form handler + '#ief_display_mode' => $this->iefHandler->getEntityFormDisplay($this->getSetting('display_mode')), // Identifies the IEF widget to which the form belongs. '#ief_id' => $this->getIefId(), // Add the pre_render callback that powers the #fieldset form element key,