entity_embed-8.x-1.x-dev/src/Plugin/entity_embed/EntityEmbedDisplay/MediaImageDecorator.php
src/Plugin/entity_embed/EntityEmbedDisplay/MediaImageDecorator.php
<?php
namespace Drupal\entity_embed\Plugin\entity_embed\EntityEmbedDisplay;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayInterface;
use Drupal\image\Plugin\Field\FieldType\ImageItem;
use Drupal\media\MediaInterface;
/**
* Decorator on all EntityEmbedDisplays that adds alt and title overriding.
*/
class MediaImageDecorator implements EntityEmbedDisplayInterface {
use StringTranslationTrait;
/**
* A string that signifies not to render the alt text.
*
* @const string
*/
const EMPTY_STRING = '""';
/**
* The decorated EntityEmbedDisplay class.
*
* @var \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayInterface
*/
private $decorated;
/**
* MediaImageDecorator constructor.
*
* @param \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayInterface $decorated
* The decorated EntityEmbedDisplay plugin.
*/
public function __construct(EntityEmbedDisplayInterface $decorated) {
$this->decorated = $decorated;
}
/**
* Passes through all unknown calls to the decorated object.
*/
public function __call($method, $args) {
return call_user_func_array([$this->decorated, $method], $args);
}
/**
* {@inheritdoc}
*/
public function access(?AccountInterface $account = NULL) {
return $this->decorated->access($account);
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
return $this->decorated->validateConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return $this->decorated->defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
return $this->decorated->calculateDependencies();
}
/**
* {@inheritdoc}
*/
public function getConfiguration() {
return $this->decorated->getConfiguration();
}
/**
* {@inheritdoc}
*/
public function getPluginDefinition() {
return $this->decorated->getPluginDefinition();
}
/**
* {@inheritdoc}
*/
public function getPluginId() {
return $this->decorated->getPluginId();
}
/**
* {@inheritdoc}
*/
public function setConfiguration(array $configuration) {
return $this->decorated->setConfiguration($configuration);
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = $this->decorated->buildConfigurationForm($form, $form_state);
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $this->decorated->getEntityFromContext();
if ($image_field = $this->getMediaImageSourceField($entity)) {
$settings = $entity->{$image_field}->getItemDefinition()->getSettings();
$attributes = $this->getAttributeValues();
$alt = isset($attributes['alt']) ? $attributes['alt'] : NULL;
$title = isset($attributes['title']) ? $attributes['title'] : NULL;
// Setting empty alt to double quotes. See ImageFieldFormatter.
if ($settings['alt_field_required'] && $alt === '') {
$alt = static::EMPTY_STRING;
}
if (!empty($settings['alt_field'])) {
// Add support for editing the alternate and title text attributes.
$form['alt'] = [
'#type' => 'textfield',
'#title' => $this->t('Alternate text'),
'#default_value' => $alt,
'#description' => $this->t('This text will be used by screen readers, search engines, or when the image cannot be loaded.'),
'#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' => 512,
'#placeholder' => $entity->{$image_field}->alt,
];
}
if (!empty($settings['title_field'])) {
$form['title'] = [
'#type' => 'textfield',
'#title' => $this->t('Title'),
'#default_value' => $title,
'#description' => t('The title is used as a tool tip when the user hovers the mouse over the image.'),
'#maxlength' => 1024,
'#placeholder' => $entity->{$image_field}->title,
];
}
}
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $this->decorated->getEntityFromContext();
if ($image_field = $this->getMediaImageSourceField($entity)) {
$settings = $entity->{$image_field}->getItemDefinition()->getSettings();
$values = $form_state->getValue(['attributes', 'data-entity-embed-display-settings']);
if (!empty($settings['alt_field'])) {
// When the alt attribute is set to two double quotes, transform it to
// the empty string: two double quotes signify "empty alt attribute".
// See ImagefieldFormatter.
if (trim($values['alt']) === static::EMPTY_STRING) {
$values['alt'] = static::EMPTY_STRING;
}
// If the alt text is unchanged from the values set on the
// field, there's no need for the alt property to be set.
elseif ($values['alt'] === $entity->{$image_field}->alt) {
$values['alt'] = '';
}
$form_state->setValue(['attributes', 'alt'], $values['alt']);
$form_state->unsetValue([
'attributes',
'data-entity-embed-display-settings',
'alt',
]);
}
if (!empty($settings['title_field'])) {
if (empty($values['title'])) {
$values['title'] = '';
}
// If the title text is unchanged from the values set on the
// field, there's no need for the title property to be set.
elseif ($values['title'] === $entity->{$image_field}->title) {
$values['title'] = '';
}
$form_state->setValue(['attributes', 'title'], $values['title']);
$form_state->unsetValue([
'attributes',
'data-entity-embed-display-settings',
'title',
]);
}
}
$this->decorated->submitConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function build() {
$build = $this->decorated->build();
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $this->decorated->getEntityFromContext();
if ($image_field = $this->getMediaImageSourceField($entity)) {
$settings = $entity->{$image_field}->getItemDefinition()->getSettings();
if (!empty($settings['alt_field']) && $this->hasAttribute('alt')) {
$entity->{$image_field}->alt = $this->getAttributeValue('alt');
$entity->thumbnail->alt = $this->getAttributeValue('alt');
}
if (!empty($settings['title_field']) && $this->hasAttribute('title')) {
$entity->{$image_field}->title = $this->getAttributeValue('title');
$entity->thumbnail->title = $this->getAttributeValue('title');
}
}
return $build;
}
/**
* Get image field from source config.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* Embedded entity.
*
* @return string|null
* String of image field name.
*/
protected function getMediaImageSourceField(EntityInterface $entity) {
if (!$entity instanceof MediaInterface) {
return NULL;
}
$field_definition = $entity->getSource()
->getSourceFieldDefinition($entity->bundle->entity);
$item_class = $field_definition->getItemDefinition()->getClass();
if ($item_class == ImageItem::class || is_subclass_of($item_class, ImageItem::class)) {
return $field_definition->getName();
}
return NULL;
}
}
