acquia_dam-1.0.0-rc1/src/Form/MediaTypeFormAlter.php
src/Form/MediaTypeFormAlter.php
<?php
declare(strict_types=1);
namespace Drupal\acquia_dam\Form;
use Drupal\acquia_dam\Client\AcquiaDamClientFactory;
use Drupal\acquia_dam\Exception\DamClientException;
use Drupal\acquia_dam\Exception\DamConnectException;
use Drupal\acquia_dam\Exception\DamServerException;
use Drupal\acquia_dam\Plugin\media\Source\Asset;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\media\MediaSourceInterface;
use Drupal\media\MediaTypeForm;
use Drupal\media\MediaTypeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Alters the media type form for DAM assets to improve field mapping UI.
*/
final class MediaTypeFormAlter implements ContainerInjectionInterface {
use StringTranslationTrait;
/**
* Entity field manager service.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* DAM client factory.
*
* @var \Drupal\acquia_dam\Client\AcquiaDamClientFactory
*/
protected $clientFactory;
/**
* Constructs a new MediaTypeFormAlter object.
*
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\acquia_dam\Client\AcquiaDamClientFactory $client_factory
* The Acquia DAM client factory.
*/
public function __construct(EntityFieldManagerInterface $entity_field_manager, AcquiaDamClientFactory $client_factory) {
$this->entityFieldManager = $entity_field_manager;
$this->clientFactory = $client_factory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = new self(
$container->get('entity_field.manager'),
$container->get('acquia_dam.client.factory')
);
$instance->setStringTranslation($container->get('string_translation'));
return $instance;
}
/**
* Alters the media type form to enhance the metadata mapping element.
*
* @param array $form
* The form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
public function formAlter(array &$form, FormStateInterface $form_state): void {
$form_object = $form_state->getFormObject();
if (!$form_object instanceof MediaTypeForm) {
return;
}
$media_type = $form_object->getEntity();
if (!$media_type instanceof MediaTypeInterface) {
return;
}
// Source is not set when the entity is initially created.
if ($media_type->get('source') === NULL) {
return;
}
$source = $media_type->getSource();
if (!$source instanceof Asset) {
return;
}
$form['source_dependent']['field_map']['#title'] = $this->t('Map Fields');
unset($form['source_dependent']['field_map']['#description']);
foreach (Element::children($form['source_dependent']['field_map']) as $child) {
unset($form['source_dependent']['field_map'][$child]);
}
$form['source_dependent']['field_map']['description'] = [
'#type' => 'markup',
'#markup' => '<p>' . $this->t('Metadata can be mapped from the DAM to Drupal entity fields. Field mappings can be configured below. Information will be mapped only if an entity field is empty.') . '</p>',
];
try {
/** @var array{fields: array<int, array<string, string>>} $metadata_list */
$metadata_list = $this->clientFactory->getSiteClient()->getDisplayKeys('all');
$metadata_field_types = [
'created_date' => 'datetime',
'filename' => 'text',
'size' => 'numeric',
'last_update_date' => 'datetime',
'file_upload_date' => 'datetime',
'expiration_date' => 'datetime',
'release_date' => 'datetime',
'deleted_date' => 'datetime',
];
foreach ($metadata_list['fields'] as $metadata_field) {
$metadata_field_types[$metadata_field['display_key']] = $metadata_field['field_type'];
}
}
catch (DamClientException | DamServerException | DamConnectException $e) {
$form['source_dependent']['field_map']['mapping'] = [
'#type' => 'markup',
'#markup' => '<p>' . $this->t('Cannot configure mapping because: @error', [
'@error' => $e->getMessage(),
]) . '</p>',
];
return;
}
$form['source_dependent']['field_map']['mapping'] = [
'#type' => 'table',
'#input' => FALSE,
'#header' => [
$this->t('DAM metadata field'),
$this->t('DAM field name'),
$this->t('DAM field type'),
$this->t('Drupal mapped field'),
],
'#rows' => [],
];
$field_map = $media_type->getFieldMap();
$dam_field_types = [
'checkboxes' => $this->t('Checkbox'),
'date' => $this->t('Date'),
'datetime' => $this->t('Date and time'),
'text_multi_line' => $this->t('Text'),
'text' => $this->t('Text'),
'selection_list' => $this->t('Dropdown'),
'limited_text_field' => $this->t('Limited text'),
'selection_list_multi' => $this->t('Palette'),
'numeric' => $this->t('Numeric'),
'text_long' => $this->t('Long text'),
];
$metadata_attributes = $source->getMetadataAttributes();
ksort($metadata_attributes);
foreach ($metadata_attributes as $attribute_name => $attribute_label) {
// The metadata field may have been removed from the DAM, but it is still
// configured to be used.
if (empty($metadata_field_types[$attribute_name])) {
continue;
}
$label = $dam_field_types[strtolower($metadata_field_types[$attribute_name])] ?? '';
if ($label === '') {
$label = ucfirst(str_replace('_', ' ', $metadata_field_types[$attribute_name]));
}
$options = [MediaSourceInterface::METADATA_FIELD_EMPTY => $this->t('- Skip field -')];
foreach ($this->entityFieldManager->getFieldDefinitions('media', $media_type->id()) as $field_name => $field) {
if ($field->getFieldStorageDefinition()->isBaseField()
&& $field_name !== 'name'
|| $field->isReadOnly()
) {
continue;
}
$field_type = $field->getType();
$metadata_type = $metadata_field_types[$attribute_name];
// Dates can only go to string, timestamp, and datetime fields.
if (!in_array($metadata_type, ['date', 'datetime'])
&& in_array($field_type, ['datetime', 'timestamp'])) {
continue;
}
$options[$field_name] = $field->getLabel();
}
$row = [
'label' => [
'#plain_text' => $attribute_label,
],
'name' => [
'#plain_text' => $attribute_name,
],
'type' => [
'#plain_text' => $label,
],
'field' => [
[
'#type' => 'select',
'#title' => $this->t('Drupal field for @title', ['@title' => $attribute_label]),
'#title_display' => 'invisible',
'#options' => $options,
'#default_value' => $field_map[$attribute_name] ?? MediaSourceInterface::METADATA_FIELD_EMPTY,
'#parents' => ['field_map', $attribute_name],
],
],
];
$form['source_dependent']['field_map']['mapping'][$attribute_name] = $row;
}
}
}
