View source
<?php
namespace Drupal\media\Form;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\editor\EditorInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\editor\Ajax\EditorDialogSave;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\filter\Plugin\FilterInterface;
use Drupal\image\Plugin\Field\FieldType\ImageItem;
use Drupal\media\MediaInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
class EditorMediaDialog extends FormBase {
protected $entityRepository;
protected $entityDisplayRepository;
public function __construct(EntityRepositoryInterface $entity_repository, EntityDisplayRepositoryInterface $entity_display_repository) {
$this->entityRepository = $entity_repository;
$this->entityDisplayRepository = $entity_display_repository;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity.repository'), $container
->get('entity_display.repository'));
}
public function getFormId() {
return 'editor_media_dialog';
}
public function buildForm(array $form, FormStateInterface $form_state, EditorInterface $editor = NULL) {
if (isset($form_state
->getUserInput()['editor_object'])) {
$editor_object = $form_state
->getUserInput()['editor_object'];
$media_embed_element = $editor_object['attributes'];
$form_state
->set('media_embed_element', $media_embed_element);
$has_caption = $editor_object['hasCaption'];
$form_state
->set('hasCaption', $has_caption)
->setCached(TRUE);
}
else {
$media_embed_element = $form_state
->get('media_embed_element');
$has_caption = $form_state
->get('hasCaption');
}
$form['#tree'] = TRUE;
$form['#attached']['library'][] = 'editor/drupal.editor.dialog';
$form['#prefix'] = '<div id="editor-media-dialog-form">';
$form['#suffix'] = '</div>';
$filters = $editor
->getFilterFormat()
->filters();
$filter_html = $filters
->get('filter_html');
$filter_align = $filters
->get('filter_align');
$filter_caption = $filters
->get('filter_caption');
$media_embed_filter = $filters
->get('media_embed');
$allowed_attributes = [];
if ($filter_html->status) {
$restrictions = $filter_html
->getHTMLRestrictions();
$allowed_attributes = $restrictions['allowed']['drupal-media'];
}
$media = $this->entityRepository
->loadEntityByUuid('media', $media_embed_element['data-entity-uuid']);
if ($image_field_name = $this
->getMediaImageSourceFieldName($media)) {
if (!empty($editor_object['hostEntityLangcode']) && $media
->hasTranslation($editor_object['hostEntityLangcode'])) {
$media = $media
->getTranslation($editor_object['hostEntityLangcode']);
}
$settings = $media->{$image_field_name}
->getItemDefinition()
->getSettings();
$alt = isset($media_embed_element['alt']) ? $media_embed_element['alt'] : NULL;
$form['alt'] = [
'#type' => 'textfield',
'#title' => $this
->t('Alternate text'),
'#default_value' => $alt,
'#description' => $this
->t('Short description of the image used by screen readers and displayed when the image is not loaded. This is important for accessibility.'),
'#required_error' => $this
->t('Alternative text is required.<br />(Only in rare cases should this be left empty. To create empty alternative text, enter <code>""</code> — two double quotes without any content).'),
'#maxlength' => 2048,
'#placeholder' => $media->{$image_field_name}->alt,
'#parents' => [
'attributes',
'alt',
],
'#access' => !empty($settings['alt_field']) && ($filter_html->status === FALSE || !empty($allowed_attributes['alt'])),
];
}
$form['align'] = [
'#title' => $this
->t('Align'),
'#type' => 'radios',
'#options' => [
'none' => $this
->t('None'),
'left' => $this
->t('Left'),
'center' => $this
->t('Center'),
'right' => $this
->t('Right'),
],
'#default_value' => empty($media_embed_element['data-align']) ? 'none' : $media_embed_element['data-align'],
'#attributes' => [
'class' => [
'container-inline',
],
],
'#parents' => [
'attributes',
'data-align',
],
'#access' => $filter_align->status && ($filter_html->status === FALSE || !empty($allowed_attributes['data-align'])),
];
$form['caption'] = [
'#title' => $this
->t('Caption'),
'#type' => 'checkbox',
'#default_value' => $has_caption === 'true',
'#parents' => [
'hasCaption',
],
'#access' => $filter_caption->status && ($filter_html->status === FALSE || !empty($allowed_attributes['data-caption'])),
];
$view_mode_options = array_intersect_key($this->entityDisplayRepository
->getViewModeOptionsByBundle('media', $media
->bundle()), $media_embed_filter->settings['allowed_view_modes']);
$default_view_mode = static::getViewModeDefaultValue($view_mode_options, $media_embed_filter, $media_embed_element['data-view-mode'] ?? NULL);
$form['view_mode'] = [
'#title' => $this
->t("Display"),
'#type' => 'select',
'#options' => $view_mode_options,
'#default_value' => $default_view_mode,
'#parents' => [
'attributes',
'data-view-mode',
],
'#access' => count($view_mode_options) >= 2,
];
$form_state
->set('filter_default_view_mode', $media_embed_filter->settings['default_view_mode']);
if ((empty($form['alt']) || $form['alt']['#access'] === FALSE) && $form['align']['#access'] === FALSE && $form['caption']['#access'] === FALSE && $form['view_mode']['#access'] === FALSE) {
$format = $editor
->getFilterFormat();
$warning = $this
->t('There is nothing to configure for this media.');
$form['no_access_notice'] = [
'#markup' => $warning,
];
if ($format
->access('update')) {
$tparams = [
'@warning' => $warning,
'@edit_url' => $format
->toUrl('edit-form')
->toString(),
'%format' => $format
->label(),
];
$form['no_access_notice']['#markup'] = $this
->t('@warning <a href="@edit_url">Edit the text format %format</a> to modify the attributes that can be overridden.', $tparams);
}
}
$form['actions'] = [
'#type' => 'actions',
];
$form['actions']['save_modal'] = [
'#type' => 'submit',
'#value' => $this
->t('Save'),
'#submit' => [],
'#ajax' => [
'callback' => '::submitForm',
'event' => 'click',
],
'#attributes' => [
'tabindex' => -1,
],
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
if (trim($form_state
->getValue([
'attributes',
'alt',
], '')) === '""') {
$form_state
->setValue([
'attributes',
'alt',
], '""');
}
if ($form_state
->hasValue([
'attributes',
'alt',
]) && trim($form_state
->getValue([
'attributes',
'alt',
])) === '') {
$form_state
->setValue([
'attributes',
'alt',
], FALSE);
}
if (!empty($form_state
->get('filter_default_view_mode')) && $form_state
->getValue([
'attributes',
'data-view-mode',
]) === $form_state
->get('filter_default_view_mode')) {
$form_state
->setValue([
'attributes',
'data-view-mode',
], FALSE);
}
if ($form_state
->getErrors()) {
unset($form['#prefix'], $form['#suffix']);
$form['status_messages'] = [
'#type' => 'status_messages',
'#weight' => -10,
];
$response
->addCommand(new HtmlCommand('#editor-media-dialog-form', $form));
}
else {
$values = [
'hasCaption' => $form_state
->getValue('hasCaption'),
'attributes' => $form_state
->getValue('attributes'),
];
$response
->addCommand(new EditorDialogSave($values));
$response
->addCommand(new CloseModalDialogCommand());
}
return $response;
}
public static function getViewModeDefaultValue(array $view_mode_options, FilterInterface $media_embed_filter, $media_element_view_mode_attribute) {
if (count($view_mode_options) < 2) {
return NULL;
}
$filter_default_view_mode = $media_embed_filter->settings['default_view_mode'];
if (!empty($media_element_view_mode_attribute) && array_key_exists($media_element_view_mode_attribute, $view_mode_options)) {
return $media_element_view_mode_attribute;
}
elseif (array_key_exists($filter_default_view_mode, $view_mode_options)) {
return $filter_default_view_mode;
}
return NULL;
}
protected function getMediaImageSourceFieldName(MediaInterface $media) {
$field_definition = $media
->getSource()
->getSourceFieldDefinition($media->bundle->entity);
$item_class = $field_definition
->getItemDefinition()
->getClass();
if (is_a($item_class, ImageItem::class, TRUE)) {
return $field_definition
->getName();
}
return NULL;
}
}