flipping_gallery-1.0.x-dev/src/Plugin/Field/FieldFormatter/FlippingGalleryImageFormatter.php
src/Plugin/Field/FieldFormatter/FlippingGalleryImageFormatter.php
<?php
namespace Drupal\flipping_gallery\Plugin\Field\FieldFormatter;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\Cache;
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\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\file\Plugin\Field\FieldFormatter\FileFormatterBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'Flipping Gallery Image' formatter.
*
* @FieldFormatter(
* id = "flipping_gallery_image",
* label = @Translation("Flipping Gallery Image"),
* description = @Translation("Formats field output as a Flipping Gallery images."),
* field_types = {"image"},
* quickedit = {"editor" = "disabled"}
* )
*/
class FlippingGalleryImageFormatter extends FileFormatterBase implements ContainerFactoryPluginInterface {
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The image style entity storage.
*
* @var \Drupal\image\ImageStyleStorageInterface
*/
protected $imageStyleStorage;
/**
* Construct a FlippingGalleryImageFormatter object.
*
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* Defines an interface for entity field definitions.
* @param array $settings
* The formatter settings.
* @param string $label
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Any third party settings.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
* @param \Drupal\Core\Entity\EntityStorageInterface $image_style_storage
* The image style storage.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, RendererInterface $renderer, AccountInterface $current_user, EntityStorageInterface $image_style_storage) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->renderer = $renderer;
$this->currentUser = $current_user;
$this->imageStyleStorage = $image_style_storage;
}
/**
* @inheritdoc
*/
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('renderer'),
$container->get('current_user'),
$container->get('entity_type.manager')->getStorage('image_style')
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'image_style' => '',
'direction' => 'forward',
'selector' => '> a',
'spacing' => 10,
'showMaximum' => 15,
'enableScroll' => TRUE,
'flipDirection' => 'bottom',
'autoplay' => FALSE,
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$description_link = Link::fromTextAndUrl(
$this->t('Configure Image Styles'),
Url::fromRoute('entity.image_style.collection')
);
$form['image_style'] = [
'#title' => $this->t('Image style'),
'#type' => 'select',
'#default_value' => $this->getSetting('image_style'),
'#empty_option' => $this->t('None (original image)'),
'#options' => image_style_options(FALSE),
'#description' => $description_link->toRenderable() + [
'#access' => $this->currentUser->hasPermission('administer image styles'),
],
];
$form['direction'] = [
'#title' => $this->t('Direction'),
'#type' => 'select',
'#options' => [
'forward' => $this->t('Forward'),
'backward' => $this->t('Backward'),
],
'#default_value' => $this->getSetting('direction'),
];
$form['selector'] = [
'#title' => $this->t('Selector'),
'#type' => 'textfield',
'#default_value' => $this->getSetting('selector'),
];
$form['spacing'] = [
'#title' => $this->t('Spacing'),
'#type' => 'number',
'#default_value' => $this->getSetting('spacing'),
];
$form['showMaximum'] = [
'#title' => $this->t('Show maximum'),
'#type' => 'number',
'#default_value' => $this->getSetting('showMaximum'),
];
$form['enableScroll'] = [
'#title' => $this->t('Enable scroll'),
'#type' => 'checkbox',
'#default_value' => $this->getSetting('enableScroll'),
];
$form['flipDirection'] = [
'#title' => $this->t('Flip direction'),
'#type' => 'select',
'#options' => [
'left' => $this->t('Left'),
'right' => $this->t('Right'),
'top' => $this->t('Top'),
'bottom' => $this->t('Bottom'),
],
'#default_value' => $this->getSetting('flipDirection'),
];
$form['autoplay'] = [
'#title' => $this->t('Autoplay'),
'#type' => 'checkbox',
'#default_value' => $this->getSetting('autoplay'),
];
return $form;
}
/**
* @inheritdoc
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$gallery_items = [];
// Puts together configurable settings in order to pass them to JS.
$params = [
'direction' => '',
'selector' => '',
'spacing' => '',
'showMaximum' => '',
'enableScroll' => '',
'flipDirection' => '',
'autoplay' => '',
];
// Takes Flipping Gallery configs apart from other field formatter settings.
$settings = $this->getSettings();
foreach ($params as $param => $value) {
$params[$param] = $settings[$param] ?? '';
}
// Gets cache tags based on the image style we use.
$base_cache_tags = [];
if (!empty($settings['image_style'])) {
$base_cache_tags = $this->imageStyleStorage->load($settings['image_style'])->getCacheTags();
}
// Creates a renderable array with the images that should be displayed.
$entities = $this->getEntitiesToView($items, $langcode);
foreach ($entities as $delta => $entity) {
// Adds an image specific cache tags.
$cache_tags = Cache::mergeTags($base_cache_tags, $entity->getCacheTags());
$gallery_items[$delta] = [
'#type' => 'html_tag',
'#tag' => 'a',
'#attributes' => [
'href' => '#',
],
[
'#theme' => 'image_formatter',
'#item' => $items[$delta],
'#image_style' => $settings['image_style'],
'#cache' => [
'tags' => $cache_tags,
],
],
];
}
// Wraps gallery items with a container, attaches libraries.
$gallery = [
'#type' => 'html_tag',
'#tag' => 'div',
'#attributes' => [
'class' => ['flipping-gallery'],
'data-configs' => Json::encode($params),
],
'#attached' => [
'library' => 'flipping_gallery/load',
],
$gallery_items,
];
return [
'#markup' => $this->renderer->render($gallery),
];
}
}
