286 lines
9.1 KiB
286 lines
9.1 KiB
<?php |
|
|
|
namespace Drupal\islandora\Form; |
|
|
|
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\Extension\ModuleHandlerInterface; |
|
use Drupal\Core\Field\WidgetBase; |
|
use Drupal\Core\Form\FormStateInterface; |
|
use Drupal\inline_entity_form\Form\EntityInlineForm; |
|
use Drupal\inline_entity_form\InlineFormInterface; |
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
|
|
|
/** |
|
* Generic entity inline form handler. |
|
*/ |
|
class FedoraResourceEntityInlineForm extends EntityInlineForm implements InlineFormInterface { |
|
|
|
/** |
|
* The entity field manager. |
|
* |
|
* @var \Drupal\Core\Entity\EntityFieldManagerInterface |
|
*/ |
|
protected $entityFieldManager; |
|
|
|
/** |
|
* The entity type manager. |
|
* |
|
* @var \Drupal\Core\Entity\EntityTypeManagerInterface |
|
*/ |
|
protected $entityTypeManager; |
|
|
|
/** |
|
* The entity type managed by this handler. |
|
* |
|
* @var \Drupal\Core\Entity\EntityTypeInterface |
|
*/ |
|
protected $entityType; |
|
|
|
/** |
|
* Module handler service. |
|
* |
|
* @var \Drupal\Core\Extension\ModuleHandlerInterface |
|
*/ |
|
protected $moduleHandler; |
|
|
|
/** |
|
* Constructs the inline entity form controller. |
|
* |
|
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager |
|
* The entity field manager. |
|
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager |
|
* The entity type manager. |
|
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler |
|
* The module handler. |
|
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type |
|
* The entity type. |
|
*/ |
|
public function __construct(EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, EntityTypeInterface $entity_type) { |
|
$this->entityFieldManager = $entity_field_manager; |
|
$this->entityTypeManager = $entity_type_manager; |
|
$this->moduleHandler = $module_handler; |
|
$this->entityType = $entity_type; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { |
|
return new static( |
|
$container->get('entity_field.manager'), |
|
$container->get('entity_type.manager'), |
|
$container->get('module_handler'), |
|
$entity_type |
|
); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getEntityType() { |
|
return $this->entityType; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getEntityTypeLabels() { |
|
$lowercase_label = $this->entityType->getLowercaseLabel(); |
|
return [ |
|
'singular' => $lowercase_label, |
|
'plural' => t('@entity_type entities', ['@entity_type' => $lowercase_label]), |
|
]; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getEntityLabel(EntityInterface $entity) { |
|
return $entity->label(); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function getTableFields($bundles) { |
|
$definitions = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType->id()); |
|
$label_key = $this->entityType->getKey('label'); |
|
$label_field_label = t('Label'); |
|
if ($label_key && isset($definitions[$label_key])) { |
|
$label_field_label = $definitions[$label_key]->getLabel(); |
|
} |
|
$bundle_key = $this->entityType->getKey('bundle'); |
|
$bundle_field_label = t('Type'); |
|
if ($bundle_key && isset($definitions[$bundle_key])) { |
|
$bundle_field_label = $definitions[$bundle_key]->getLabel(); |
|
} |
|
|
|
$fields = []; |
|
$fields['label'] = [ |
|
'type' => 'label', |
|
'label' => $label_field_label, |
|
'weight' => 1, |
|
]; |
|
if (count($bundles) > 1) { |
|
$fields[$bundle_key] = [ |
|
'type' => 'field', |
|
'label' => $bundle_field_label, |
|
'weight' => 2, |
|
'display_options' => [ |
|
'type' => 'entity_reference_label', |
|
'settings' => ['link' => FALSE], |
|
], |
|
]; |
|
} |
|
|
|
return $fields; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function entityForm(array $entity_form, FormStateInterface $form_state) { |
|
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ |
|
$entity = $entity_form['#entity']; |
|
$form_display = $this->getFormDisplay($entity, $entity_form['#form_mode']); |
|
$form_display->buildForm($entity, $entity_form, $form_state); |
|
$entity_form['#ief_element_submit'][] = [get_class($this), 'submitCleanFormState']; |
|
// Allow other modules to alter the form. |
|
$this->moduleHandler->alter('inline_entity_form_entity_form', $entity_form, $form_state); |
|
|
|
return $entity_form; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function entityFormValidate(array &$entity_form, FormStateInterface $form_state) { |
|
// Perform entity validation only if the inline form was submitted, |
|
// skipping other requests such as file uploads. |
|
$triggering_element = $form_state->getTriggeringElement(); |
|
if (!empty($triggering_element['#ief_submit_trigger'])) { |
|
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ |
|
$entity = $entity_form['#entity']; |
|
$this->buildEntity($entity_form, $entity, $form_state); |
|
$form_display = $this->getFormDisplay($entity, $entity_form['#form_mode']); |
|
$form_display->validateFormValues($entity, $entity_form, $form_state); |
|
$entity->setValidationRequired(FALSE); |
|
|
|
foreach ($form_state->getErrors() as $name => $message) { |
|
// $name may be unknown in $form_state and |
|
// $form_state->setErrorByName($name, $message) |
|
// may suppress the error message. |
|
$form_state->setError($triggering_element, $message); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function entityFormSubmit(array &$entity_form, FormStateInterface $form_state) { |
|
$form_state->cleanValues(); |
|
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ |
|
$entity = $entity_form['#entity']; |
|
$this->buildEntity($entity_form, $entity, $form_state); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function save(EntityInterface $entity) { |
|
$entity->save(); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function delete($ids, $context) { |
|
$storage_handler = $this->entityTypeManager->getStorage($this->entityType->id()); |
|
$entities = $storage_handler->loadMultiple($ids); |
|
$storage_handler->delete($entities); |
|
} |
|
|
|
/** |
|
* Builds an updated entity object based upon the submitted form values. |
|
* |
|
* @param array $entity_form |
|
* The entity form. |
|
* @param \Drupal\Core\Entity\ContentEntityInterface $entity |
|
* The entity. |
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
|
* The current state of the form. |
|
*/ |
|
protected function buildEntity(array $entity_form, ContentEntityInterface $entity, FormStateInterface $form_state) { |
|
$form_display = $this->getFormDisplay($entity, $entity_form['#form_mode']); |
|
$form_display->extractFormValues($entity, $entity_form, $form_state); |
|
// Invoke all specified builders for copying form values to entity fields. |
|
if (isset($entity_form['#entity_builders'])) { |
|
foreach ($entity_form['#entity_builders'] as $function) { |
|
call_user_func_array($function, [ |
|
$entity->getEntityTypeId(), |
|
$entity, |
|
&$entity_form, |
|
&$form_state, |
|
]); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Cleans up the form state for a submitted entity form. |
|
* |
|
* After field_attach_submit() has run and the form has been closed, the form |
|
* state still contains field data in $form_state->get('field'). Unless that |
|
* data is removed, the next form with the same #parents (reopened add form, |
|
* for example) will contain data (i.e. uploaded files) from the previous |
|
* form. |
|
* |
|
* @param array $entity_form |
|
* The entity form. |
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
|
* The form state of the parent form. |
|
*/ |
|
public static function submitCleanFormState(&$entity_form, FormStateInterface $form_state) { |
|
$info = \Drupal::entityTypeManager()->getDefinition($entity_form['#entity_type']); |
|
if (!$info->get('field_ui_base_route')) { |
|
// The entity type is not fieldable, nothing to cleanup. |
|
return; |
|
} |
|
|
|
$bundle = $entity_form['#entity']->bundle(); |
|
$instances = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_form['#entity_type'], $bundle); |
|
foreach ($instances as $instance) { |
|
$field_name = $instance->getName(); |
|
if (!empty($entity_form[$field_name]['#parents'])) { |
|
$parents = $entity_form[$field_name]['#parents']; |
|
array_pop($parents); |
|
if (!empty($parents)) { |
|
$field_state = array(); |
|
WidgetBase::setWidgetState($parents, $field_name, $form_state, $field_state); |
|
} |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Gets the form display for the given entity. |
|
* |
|
* @param \Drupal\Core\Entity\ContentEntityInterface $entity |
|
* The entity. |
|
* @param string $form_mode |
|
* The form mode. |
|
* |
|
* @return \Drupal\Core\Entity\Display\EntityFormDisplayInterface |
|
* The form display. |
|
*/ |
|
protected function getFormDisplay(ContentEntityInterface $entity, $form_mode) { |
|
return EntityFormDisplay::collectRenderDisplay($entity, $form_mode); |
|
} |
|
|
|
}
|
|
|