View source
<?php
namespace Drupal\formatter_suite\Plugin\Field\FieldFormatter;
use Drupal\Core\Entity\EntityRepository;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\Component\Utility\Html;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\field\FieldConfigInterface;
use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter;
use Drupal\formatter_suite\Branding;
use Drupal\formatter_suite\Utilities;
class GeneralImageFormatter extends ImageFormatter {
protected $entityRepository;
public function __construct($pluginId, $pluginDefinition, FieldDefinitionInterface $fieldDefinition, array $settings, $label, $view_mode, array $thirdPartySettings, AccountInterface $currentUser, EntityStorageInterface $imageStyleStorage, EntityRepository $entityRepository) {
parent::__construct($pluginId, $pluginDefinition, $fieldDefinition, $settings, $label, $view_mode, $thirdPartySettings, $currentUser, $imageStyleStorage);
$this->entityRepository = $entityRepository;
}
public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
return new static($pluginId, $pluginDefinition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], $container
->get('current_user'), $container
->get('entity_type.manager')
->getStorage('image_style'), $container
->get('entity.repository'));
}
protected static function getCaptionLocations() {
return [
'none' => t('Do not display an image caption'),
'above' => t('Display an image caption above the image'),
'below' => t('Display an image caption below the image'),
];
}
protected static function getOpenLinkInValues() {
return [
'_self' => t('Open in the same tab/window'),
'_blank' => t('Open in a new tab/window'),
'download' => t('Download the entity or image file'),
];
}
protected static function getLinkTypes() {
return [
'content' => t("Link to the image field's entity"),
'file' => t("Link to the image file"),
];
}
public static function defaultSettings() {
return array_merge([
'captionLocation' => 'none',
'captionIncludeTitle' => FALSE,
'captionIncludeFilename' => FALSE,
'captionIncludeSize' => FALSE,
'captionIncludeDimensions' => FALSE,
'captionIncludeMime' => FALSE,
'classes' => '',
'openLinkIn' => '_self',
], parent::defaultSettings());
}
public function settingsSummary() {
$this
->sanitizeSettings();
$imageStyles = image_style_options(FALSE);
unset($imageStyles['']);
$styleChoice = $this
->getSetting('image_style');
$currentStyle = NULL;
if (isset($imageStyles[$styleChoice]) === TRUE) {
$currentStyle = $imageStyles[$styleChoice];
}
$fieldDefinition = $this->fieldDefinition;
$fieldSettings = $fieldDefinition
->getSettings();
$hasTitle = FALSE;
if (isset($fieldSettings['title_field']) === TRUE && boolval($fieldSettings['title_field']) === TRUE) {
$hasTitle = TRUE;
}
$summary = [];
if ($currentStyle === NULL) {
$summary[] = $this
->t('Original image');
}
else {
$summary[] = $this
->t('Image style "@style"', [
'@style' => $currentStyle,
]);
}
$linkChoice = $this
->getSetting('image_link');
$linkTypes = self::getLinkTypes();
if (isset($linkTypes[$linkChoice]) === TRUE) {
$summary[] = $linkTypes[$linkChoice];
$openInChoice = $this
->getSetting('openLinkIn');
$openInValues = self::getOpenLinkInValues();
if ($openInChoice !== 'download') {
$summary[] = $openInValues[$openInChoice];
}
elseif ($linkChoice !== 'file') {
$summary[] = $openInValues['_blank'];
}
else {
$summary[] = $openInValues[$openInChoice];
}
}
$captionChoice = $this
->getSetting('captionLocation');
$captionLocations = self::getCaptionLocations();
if ($captionChoice !== 'none' && isset($captionLocations[$captionChoice]) === TRUE) {
$includes = [];
if ($hasTitle === TRUE && $this
->getSetting('captionIncludeTitle') === TRUE) {
$includes[] = (string) $this
->t('title');
}
if ($this
->getSetting('captionIncludeFilename') === TRUE) {
$includes[] = (string) $this
->t('file name');
}
if ($this
->getSetting('captionIncludeSize') === TRUE) {
$includes[] = (string) $this
->t('size');
}
if ($this
->getSetting('captionIncludeDimensions') === TRUE) {
$includes[] = (string) $this
->t('dimensions');
}
if ($this
->getSetting('captionIncludeMime') === TRUE) {
$includes[] = (string) $this
->t('MIME type');
}
if (empty($includes) === FALSE) {
switch ($captionChoice) {
case 'above':
$summary[] = $this
->t('Caption above: @list', [
'@list' => implode(', ', $includes),
]);
break;
default:
case 'below':
$summary[] = $this
->t('Caption below: @list', [
'@list' => implode(', ', $includes),
]);
break;
}
}
}
return $summary;
}
protected function getDescription() {
return $this
->t("Show an image using a selected style. Optionally link the image to the content entity or the image file, and optionally include a caption above or below the image.");
}
public function settingsForm(array $form, FormStateInterface $formState) {
$marker = rand();
$elements = [];
$elements = Branding::addFieldFormatterBranding($elements);
$elements['#attached']['library'][] = 'formatter_suite/formatter_suite.fieldformatter';
$elements['description'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $this
->getDescription(),
'#weight' => -1000,
'#attributes' => [
'class' => [
'formatter_suite-settings-description',
],
],
];
$weight = 100;
$fieldDefinition = $this->fieldDefinition;
$fieldSettings = $fieldDefinition
->getSettings();
$hasTitle = FALSE;
if (isset($fieldSettings['title_field']) === TRUE && boolval($fieldSettings['title_field']) === TRUE) {
$hasTitle = TRUE;
}
$imageStyles = image_style_options(FALSE);
$imageStylesPage = Link::fromTextAndUrl($this
->t('Configure image styles'), Url::fromRoute('entity.image_style.collection'));
$imageStyleAllowed = $this->currentUser
->hasPermission('administer image styles');
$elements['image_style'] = [
'#title' => $this
->t('Image style'),
'#type' => 'select',
'#options' => $imageStyles,
'#empty_option' => $this
->t('None (original image)'),
'#default_value' => $this
->getSetting('image_style'),
'#description' => $imageStylesPage
->toRenderable() + [
'#access' => $imageStyleAllowed,
],
'#weight' => $weight++,
];
$elements['classes'] = [
'#title' => $this
->t('Custom classes'),
'#type' => 'textfield',
'#size' => 10,
'#default_value' => $this
->getSetting('classes'),
'#weight' => $weight++,
'#attributes' => [
'autocomplete' => 'off',
'autocapitalize' => 'none',
'spellcheck' => 'false',
'autocorrect' => 'off',
],
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-classes',
],
],
];
$elements['sectionBreak2'] = [
'#markup' => '<div class="formatter_suite-section-break"></div>',
'#weight' => $weight++,
];
$elements['image_link'] = [
'#title' => $this
->t('Link image'),
'#type' => 'select',
'#options' => self::getLinkTypes(),
'#empty_option' => $this
->t('Do not link the image'),
'#default_value' => $this
->getSetting('image_link'),
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-link-type',
],
],
'#attributes' => [
'class' => [
'image_link-' . $marker,
],
],
'#weight' => $weight++,
];
$elements['openLinkIn'] = [
'#title' => $this
->t('Use link to'),
'#type' => 'select',
'#options' => self::getOpenLinkInValues(),
'#default_value' => $this
->getSetting('openLinkIn'),
'#weight' => $weight++,
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-open-link-in',
],
],
'#states' => [
'invisible' => [
'.image_link-' . $marker => [
'value' => '',
],
],
],
];
$elements['sectionBreak3'] = [
'#markup' => '<div class="formatter_suite-section-break"></div>',
'#weight' => $weight++,
];
$elements['captionLocation'] = [
'#title' => $this
->t('Caption location'),
'#type' => 'select',
'#options' => self::getCaptionLocations(),
'#default_value' => $this
->getSetting('captionLocation'),
'#weight' => $weight++,
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-caption-location',
],
],
'#attributes' => [
'class' => [
'captionLocation-' . $marker,
],
],
];
if ($hasTitle === TRUE) {
$elements['captionIncludeTitle'] = [
'#title' => $this
->t('Include title in caption'),
'#type' => 'checkbox',
'#default_value' => $this
->getSetting('captionIncludeTitle'),
'#weight' => $weight++,
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-caption-include-title',
],
],
'#states' => [
'invisible' => [
'.captionLocation-' . $marker => [
'value' => 'none',
],
],
],
];
}
$elements['captionIncludeFilename'] = [
'#title' => $this
->t('Include file name in caption'),
'#type' => 'checkbox',
'#default_value' => $this
->getSetting('captionIncludeFilename'),
'#weight' => $weight++,
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-caption-include-filename',
],
],
'#states' => [
'invisible' => [
'.captionLocation-' . $marker => [
'value' => 'none',
],
],
],
];
$elements['captionIncludeSize'] = [
'#title' => $this
->t('Include file size in caption'),
'#type' => 'checkbox',
'#default_value' => $this
->getSetting('captionIncludeSize'),
'#weight' => $weight++,
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-caption-include-size',
],
],
'#states' => [
'invisible' => [
'.captionLocation-' . $marker => [
'value' => 'none',
],
],
],
];
$elements['captionIncludeDimensions'] = [
'#title' => $this
->t('Include image dimensions in caption'),
'#type' => 'checkbox',
'#default_value' => $this
->getSetting('captionIncludeDimensions'),
'#weight' => $weight++,
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-caption-include-dimensions',
],
],
'#states' => [
'invisible' => [
'.captionLocation-' . $marker => [
'value' => 'none',
],
],
],
];
$elements['captionIncludeMime'] = [
'#title' => $this
->t('Include MIME type in caption'),
'#type' => 'checkbox',
'#default_value' => $this
->getSetting('captionIncludeMime'),
'#weight' => $weight++,
'#wrapper_attributes' => [
'class' => [
'formatter_suite-general-image-caption-include-mime',
],
],
'#states' => [
'invisible' => [
'.captionLocation-' . $marker => [
'value' => 'none',
],
],
],
];
return $elements;
}
protected function sanitizeSettings() {
$imageLink = $this
->getSetting('image_link');
$openLinkIn = $this
->getSetting('openLinkIn');
$captionLocation = $this
->getSetting('captionLocation');
$captionIncludeTitle = $this
->getSetting('captionIncludeTitle');
$captionIncludeFilename = $this
->getSetting('captionIncludeFilename');
$captionIncludeSize = $this
->getSetting('captionIncludeSize');
$captionIncludeDimensions = $this
->getSetting('captionIncludeDimensions');
$captionIncludeMime = $this
->getSetting('captionIncludeMime');
$defaults = $this
->defaultSettings();
if (isset(self::getLinkTypes()[$imageLink]) === FALSE) {
$this
->setSetting('image_link', $defaults['image_link']);
}
if (isset($this
->getOpenLinkInValues()[$openLinkIn]) === FALSE) {
$this
->setSetting('openLinkIn', $defaults['openLinkIn']);
}
if (isset($this
->getCaptionLocations()[$captionLocation]) === FALSE) {
$this
->setSetting('captionLocation', $defaults['captionLocation']);
}
$this
->setSetting('captionIncludeTitle', boolval($captionIncludeTitle));
$this
->setSetting('captionIncludeFilename', boolval($captionIncludeFilename));
$this
->setSetting('captionIncludeSize', boolval($captionIncludeSize));
$this
->setSetting('captionIncludeDimensions', boolval($captionIncludeDimensions));
$this
->setSetting('captionIncludeMime', boolval($captionIncludeMime));
}
public function viewElements(FieldItemListInterface $items, $langCode) {
if ($items
->isEmpty() === TRUE) {
$defaultImage = $this
->getFieldSetting('default_image');
$fieldDef = $this->fieldDefinition;
if (empty($defaultImage['uuid']) === TRUE && $fieldDef instanceof FieldConfigInterface) {
$storageDef = $fieldDef
->getFieldStorageDefinition();
$defaultImage = $storageDef
->getSetting('default_image');
}
if (empty($defaultImage['uuid']) === TRUE) {
return [];
}
$imageFile = $this->entityRepository
->loadEntityByUuid('file', $defaultImage['uuid']);
if ($imageFile === NULL) {
return [];
}
$items = clone $items;
$items
->setValue([
'target_id' => $imageFile
->id(),
'alt' => $defaultImage['alt'],
'title' => $defaultImage['title'],
'width' => $defaultImage['width'],
'height' => $defaultImage['height'],
'entity' => $imageFile,
'_loaded' => TRUE,
'_is_default' => TRUE,
]);
$imageFile->_referringItem = $items[0];
}
$files = $this
->getEntitiesToView($items, $langCode);
if (empty($files) === TRUE) {
return [];
}
$this
->sanitizeSettings();
$classes = $this
->getSetting('classes');
$openLinkIn = $this
->getSetting('openLinkIn');
$captionLocation = $this
->getSetting('captionLocation');
$captionIncludeTitle = $this
->getSetting('captionIncludeTitle');
$captionIncludeFilename = $this
->getSetting('captionIncludeFilename');
$captionIncludeSize = $this
->getSetting('captionIncludeSize');
$captionIncludeDimensions = $this
->getSetting('captionIncludeDimensions');
$captionIncludeMime = $this
->getSetting('captionIncludeMime');
if ($captionIncludeTitle === FALSE && $captionIncludeFilename === FALSE && $captionIncludeSize === FALSE && $captionIncludeDimensions === FALSE && $captionIncludeMime === FALSE) {
$captionLocation = 'none';
}
$parentElements = parent::viewElements($items, $langCode);
$classes = explode(' ', $classes);
$classes[] = 'formatter_suite-general-image';
$elements = [];
foreach ($items as $delta => $item) {
if (isset($parentElements[$delta]) !== TRUE) {
continue;
}
$url = $parentElements[$delta]['#url'];
$mime = $files[$delta]
->getMimeType();
if ($url !== NULL) {
$urlOptions = $url
->getOptions();
if (isset($urlOptions['attributes']) === FALSE) {
$urlOptions['attributes'] = [];
}
$urlOptions['attributes']['type'] = $mime;
switch ($openLinkIn) {
case '_self':
$urlOptions['attributes']['target'] = '_self';
break;
case '_blank':
$urlOptions['attributes']['target'] = '_blank';
break;
case 'download':
$urlOptions['attributes']['download'] = '';
break;
}
$url
->setOptions($urlOptions);
$parentElements[$delta]['#url'] = $url;
}
$imageWeight = 0;
$captionWeight = 0;
$itemClasses = array_merge([], $classes);
$caption = [];
if ($captionLocation !== 'none') {
switch ($captionLocation) {
case 'above':
$captionWeight = 0;
$imageWeight = 1000;
$itemClasses[] = 'formatter_suite-general-image-above';
break;
default:
case 'below':
$imageWeight = 0;
$captionWeight = 1000;
$itemClasses[] = 'formatter_suite-general-image-below';
break;
}
$title = '';
if ($captionIncludeTitle === TRUE) {
if (isset($item->title) === TRUE) {
$title = $item->title;
}
else {
$title = $files[$delta]
->label();
}
if (empty($title) === FALSE) {
if ($url === NULL) {
$caption['title'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => Html::escape($title),
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-title',
],
],
];
}
else {
$localUrl = clone $url;
$caption['title'] = [
'#type' => 'link',
'#title' => $title,
'#options' => $localUrl
->getOptions(),
'#url' => $localUrl,
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-title',
],
],
];
}
}
}
if ($captionIncludeFilename === TRUE) {
$filename = $files[$delta]
->getFilename();
if (empty($title) === TRUE || $title !== $filename) {
if ($url === NULL) {
$caption['filename'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => Html::escape($filename),
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-filename',
],
],
];
}
else {
$localUrl = clone $url;
$caption['filename'] = [
'#type' => 'link',
'#title' => $filename,
'#options' => $localUrl
->getOptions(),
'#url' => $localUrl,
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-filename',
],
],
];
}
}
}
if ($captionIncludeSize === TRUE) {
$bytes = Utilities::formatBytes($files[$delta]
->getSize(), 1000, FALSE, 2);
if ($url === NULL) {
$caption['size'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $bytes,
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-size',
],
],
];
}
else {
$localUrl = clone $url;
$caption['size'] = [
'#type' => 'link',
'#title' => $bytes,
'#options' => $localUrl
->getOptions(),
'#url' => $localUrl,
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-size',
],
],
];
}
}
if ($captionIncludeDimensions === TRUE) {
$x = " ⨉ ";
$text = $item->width . $x . $item->height;
if ($url === NULL) {
$caption['dimensions'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $text,
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-dimensions',
],
],
];
}
else {
$localUrl = clone $url;
$caption['dimensions'] = [
'#type' => 'link',
'#title' => $text,
'#options' => $localUrl
->getOptions(),
'#url' => $localUrl,
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-dimensions',
],
],
];
}
}
if ($captionIncludeMime === TRUE) {
if ($url === NULL) {
$caption['mime'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => Html::escape($mime),
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-mime',
],
],
];
}
else {
$localUrl = clone $url;
$caption['mime'] = [
'#type' => 'link',
'#title' => $mime,
'#options' => $localUrl
->getOptions(),
'#url' => $localUrl,
'#weight' => $captionWeight++,
'#attributes' => [
'class' => [
'formatter_suite-image-caption-mime',
],
],
];
}
}
}
$parentElements[$delta]['#weight'] = $imageWeight;
$parentElements[$delta]['#theme'] = 'formatter_suite_general_image_formatter';
if ($url === NULL) {
$parentElements[$delta]['#item_attributes']['class'] = [
'formatter_suite-image',
];
}
else {
$urlOptions = $url
->getOptions();
if (isset($urlOptions['attributes']) === TRUE) {
$urlAttributes = $urlOptions['attributes'];
$parentElements[$delta]['#attributes'] = $urlAttributes + [
'class' => [
'formatter_suite-image',
],
];
}
else {
$parentElements[$delta]['#attributes']['class'] = [
'formatter_suite-image',
];
}
}
$elements[$delta] = [
'#type' => 'container',
'#attributes' => [
'class' => $itemClasses,
],
'#attached' => [
'library' => [
'formatter_suite/formatter_suite.usage',
],
],
'image' => $parentElements[$delta],
];
if (empty($caption) === FALSE) {
$elements[$delta] += $caption;
}
}
return $elements;
}
}