View source
<?php
namespace Drupal\bynder\Plugin\Field\FieldFormatter;
use Drupal\bynder\BynderApiInterface;
use Drupal\bynder\Plugin\MediaEntity\Type\Bynder;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\media_entity\Entity\MediaBundle;
use Symfony\Component\DependencyInjection\ContainerInterface;
class BynderFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
protected $configFactory;
protected $currentUser;
protected $bynder;
protected $renderer;
protected $entityFieldManager;
protected $entityTypeManager;
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, ConfigFactoryInterface $config_factory, AccountProxyInterface $current_user, BynderApiInterface $bynder, RendererInterface $renderer_object, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->configFactory = $config_factory;
$this->currentUser = $current_user;
$this->bynder = $bynder;
$this->renderer = $renderer_object;
$this->entityFieldManager = $entity_field_manager;
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], $container
->get('config.factory'), $container
->get('current_user'), $container
->get('bynder_api'), $container
->get('renderer'), $container
->get('entity_field.manager'), $container
->get('entity_type.manager'));
}
public static function defaultSettings() {
return [
'thumbnail' => 'webimage',
'alt_field' => '',
'title_field' => '',
] + parent::defaultSettings();
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements = parent::settingsForm($form, $form_state);
$derivatives = array_merge([
'mini',
'webimage',
'thul',
], array_map(function ($item) {
return $item['prefix'];
}, $this->bynder
->getDerivatives()));
$elements['thumbnail'] = [
'#type' => 'select',
'#options' => array_combine($derivatives, $derivatives),
'#title' => $this
->t('Derivative'),
'#description' => $this
->t('Select the name of the derivative to be used to display the image. Besides custom derivatives that you created in Bynder there are also default thumbnail sizes available that can be used. Go to @form and reload derivatives.', [
'@form' => Link::createFromRoute($this
->t('Bynder configuration form'), 'bynder.configuration_form')
->toString(),
]),
'#default_value' => $this
->getSetting('thumbnail'),
];
$field_candidates = $this
->getAttributesFieldsCandidates();
$elements['alt_field'] = [
'#type' => 'select',
'#options' => $field_candidates,
'#title' => $this
->t('Alt attribute field'),
'#description' => $this
->t('Select the name of the field that should be used for the "alt" attribute of the image.'),
'#default_value' => $this
->getSetting('alt_field'),
'#empty_value' => '',
];
$elements['title_field'] = [
'#type' => 'select',
'#options' => $field_candidates,
'#title' => $this
->t('Title attribute field'),
'#description' => $this
->t('Select the name of the field that should be used for the "title" attribute of the image.'),
'#default_value' => $this
->getSetting('alt_field'),
'#empty_value' => '',
];
return $elements;
}
protected function getAttributesFieldsCandidates() {
$allowed_field_types = [
'string',
'string_long',
'text',
'text_long',
];
$handler_settings = NULL;
if (strpos($this->fieldDefinition
->getSetting('handler'), 'default:') === 0) {
$handler_settings = $this->fieldDefinition
->getSetting('handler_settings');
}
$bundles = [];
if ($handler_settings && is_array($handler_settings['target_bundles'])) {
foreach ($handler_settings['target_bundles'] as $bundle) {
$bundle_entity = $this->entityTypeManager
->getStorage('media_bundle')
->load($bundle);
if ($bundle_entity && $bundle_entity
->getType() instanceof Bynder) {
$bundles[] = $bundle_entity;
}
}
}
else {
foreach ($this->entityTypeManager
->getStorage('media_bundle')
->loadMultiple() as $bundle_entity) {
if ($bundle_entity && $bundle_entity
->getType() instanceof Bynder) {
$bundles[] = $bundle_entity;
}
}
}
$options = [];
foreach ($bundles as $bundle_entity) {
foreach ($this->entityFieldManager
->getFieldDefinitions('media', $bundle_entity
->id()) as $field_name => $field) {
if (in_array($field
->getType(), $allowed_field_types)) {
$options[$field_name] = $field
->getLabel();
}
}
}
return $options;
}
public function settingsSummary() {
$summary = parent::settingsSummary();
$settings = $this
->getSettings();
$summary[] = $this
->t('Derivative: @style', [
'@style' => $settings['thumbnail'],
]);
$field_candidates = $this
->getAttributesFieldsCandidates();
if (empty($settings['title_field'])) {
$summary[] = $this
->t('Title attribute not displayed (not recommended).');
}
else {
$summary[] = $this
->t('Title attribute field: @field', [
'@field' => $field_candidates[$settings['title_field']],
]);
}
if (empty($settings['alt_field'])) {
$summary[] = $this
->t('Alt attribute not displayed (not recommended).');
}
else {
$summary[] = $this
->t('Alt attribute field: @field', [
'@field' => $field_candidates[$settings['alt_field']],
]);
}
return $summary;
}
public function viewElements(FieldItemListInterface $items, $langcode) {
$settings = $this
->getSettings();
$element = [];
$is_entityreference = $this->fieldDefinition
->getType() == 'entity_reference';
foreach ($items as $delta => $item) {
if ($media_entity = $is_entityreference ? $item->entity : $items
->getEntity()) {
$type_plugin = $media_entity->bundle->entity
->getType();
if ($type_plugin instanceof Bynder && ($thumbnails = $type_plugin
->getField($media_entity, 'thumbnail_urls'))) {
$element['#attached']['library'][] = 'bynder/formatter';
$element[$delta]['bynder_wrapper'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'bynder-wrapper',
],
],
];
$thumbnail_uri = isset($thumbnails[$settings['thumbnail']]) ? $thumbnails[$settings['thumbnail']] : $thumbnails['webimage'];
$element[$delta]['bynder_wrapper']['image'] = [
'#theme' => 'image',
'#uri' => $thumbnail_uri,
'#attributes' => [
'class' => [
'bynder-image',
],
],
];
if ($settings['title_field'] && $media_entity
->hasField($settings['title_field']) && !$media_entity
->get($settings['title_field'])
->isEmpty()) {
$element[$delta]['bynder_wrapper']['image']['#title'] = $media_entity
->get($settings['title_field'])->value;
}
if ($settings['alt_field'] && $media_entity
->hasField($settings['alt_field']) && !$media_entity
->get($settings['alt_field'])
->isEmpty()) {
$element[$delta]['bynder_wrapper']['image']['#alt'] = $media_entity
->get($settings['alt_field'])->value;
}
$this->renderer
->addCacheableDependency($element[$delta]['bynder_wrapper']['image'], $item);
$element[$delta]['bynder_wrapper']['usage_image'] = [
'#theme' => 'image',
'#uri' => \Drupal::moduleHandler()
->getModule('bynder')
->getPath() . '/images/icons/bynder-logo.png',
'#alt' => 'usage-image',
'#title' => $this
->t('Usage info is not available yet. Usage restriction level: @restriction', [
'@restriction' => get_media_restriction($type_plugin
->getField($media_entity, 'propertyOptions')),
]),
'#attributes' => [
'class' => [
'usage-image',
],
],
'#access' => AccessResult::allowedIfHasPermission($this->currentUser, 'view bynder media usage'),
];
$this->renderer
->addCacheableDependency($element[$delta]['bynder_wrapper']['usage_image'], $this->configFactory
->get('bynder.settings'));
}
}
}
return $element;
}
public static function isApplicable(FieldDefinitionInterface $field_definition) {
if ($field_definition
->getType() == 'entity_reference') {
if ($field_definition
->getFieldStorageDefinition()
->getSetting('target_type') == 'media') {
if (strpos($field_definition
->getSetting('handler'), 'default:') === 0) {
$handler_settings = $field_definition
->getSetting('handler_settings');
if ($handler_settings['target_bundles'] === NULL) {
return TRUE;
}
elseif (is_array($handler_settings['target_bundles'])) {
foreach ($handler_settings['target_bundles'] as $bundle) {
$bundle_entity = \Drupal::entityTypeManager()
->getStorage('media_bundle')
->load($bundle);
if ($bundle_entity
->getType() instanceof Bynder) {
return TRUE;
}
}
}
}
else {
return TRUE;
}
}
return FALSE;
}
elseif (in_array($field_definition
->getType(), [
'string',
'string_long',
])) {
if ($field_definition
->getTargetEntityTypeId() != 'media') {
return FALSE;
}
if (!($bundle = $field_definition
->getTargetBundle()) || !($bundle = MediaBundle::load($field_definition
->getTargetBundle()))) {
return FALSE;
}
$type = $bundle
->getType();
if (!$type instanceof Bynder) {
return FALSE;
}
if ($type
->getConfiguration()['source_field'] != $field_definition
->getName()) {
return FALSE;
}
return TRUE;
}
}
}