progressive_image_loading-8.x-1.x-dev/src/Plugin/Field/FieldFormatter/BackgroundResponsiveImageFormatter.php
src/Plugin/Field/FieldFormatter/BackgroundResponsiveImageFormatter.php
<?php
namespace Drupal\progressive_image_loading\Plugin\Field\FieldFormatter;
use Drupal\breakpoint\BreakpointManagerInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\responsive_image\Plugin\Field\FieldFormatter\ResponsiveImageFormatter;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Implementation of the 'Background Responsive Image' formatter.
*
* @FieldFormatter(
* id = "progressive_image_loading_background_responsive_image",
* label = @Translation("Background Responsive Image (Progressive Image Loading)"),
* field_types = {
* "image"
* },
* quickedit = {
* "editor" = "image"
* }
* )
*/
class BackgroundResponsiveImageFormatter extends ResponsiveImageFormatter {
use BackgroundImageFormatterBaseTrait;
/**
* The breakpoint manager.
*
* @var \Drupal\breakpoint\BreakpointManagerInterface
*/
protected $breakpointManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->setProgressiveImageLoadingManager($container->get('progressive_image_loading.manager'));
$instance->setBreakpointManager($container->get('breakpoint.manager'));
return $instance;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = parent::viewElements($items, $langcode);
foreach ($elements as $delta => $element) {
foreach ($this->itemClasses as $class) {
$elements[$delta]['#item_attributes']['class'][] = $class;
}
// Build tye background data attributes by breakpoint, we only support
// 1x multiplier and image style as image mapping type. Otherwise we can't
// build the element attributes as our lazy loader expects.
// We need a breakpoint based list: data-background-image-BREAKPOINT.
$responsive_image_style = $this->responsiveImageStyleStorage->load($elements[$delta]['#responsive_image_style_id']);
if ($responsive_image_style) {
$breakpoint_group = $responsive_image_style->getBreakpointGroup();
$breakpoints = array_reverse($this->breakpointManager->getBreakpointsByGroup($breakpoint_group));
foreach ($responsive_image_style->getKeyedImageStyleMappings() as $breakpoint_id => $multipliers) {
if (!empty($breakpoints[$breakpoint_id]) && !empty($multipliers['1x']) && $multipliers['1x']['image_mapping_type'] == 'image_style') {
$breakpoint_name = preg_replace('/^' . $breakpoint_group . '\./', '', $multipliers['1x']['breakpoint_id']);
/** @var \Drupal\Core\Template\Attribute $source */
$source = _responsive_image_build_source_attributes(['uri' => $elements[$delta]['#item']->entity->getFileUri()], $breakpoints[$breakpoint_id], ['1x' => $multipliers['1x']]);
[$url] = explode(' ', $source->storage()['srcset']->value());
$elements[$delta]['#item_attributes']['data-background-image-' . $breakpoint_name] = $url;
if ($multipliers['1x']['image_mapping'] == $responsive_image_style->getFallbackImageStyle()) {
$elements[$delta]['#item_attributes']['data-background-image'] = $url;
$style = 'background-image: url(' . $this->progressiveImageLoadingManager->createPlaceholder($url) . ');';
$elements[$delta]['#item_attributes']['style'] = empty($elements[$delta]['#item_attributes']['style']) ? $style : $style . ' ' . $elements[$delta]['#item_attributes']['style'];
}
}
}
}
}
return $elements;
}
/**
* Sets the breakpoint manager.
*
* @param \Drupal\breakpoint\BreakpointManagerInterface $breakpoint_manager
* The breakpoint manager.
*
* @return $this
*/
protected function setBreakpointManager(BreakpointManagerInterface $breakpoint_manager) {
$this->breakpointManager = $breakpoint_manager;
return $this;
}
}
