You are here

function template_preprocess_formatter_suite_image_embed_style in Formatter Suite 8

Prepares variables for image embed style template.

This template is used by this module's ImageEmbedDataFormatter by way of the 'formatter_suite_image_embed_formatter' template. The template's job is to look up the image style, compare the styled image width and height to any limits imposed by the formatter, and then optionally embed the styled image as a data URL instead of as a file URL.

Incoming variables:

  • 'theme': the name of the theme to use.
  • 'attributes': a copy of 'item_attributes'.
  • 'width': the original image width.
  • 'height': the original image height.
  • 'alt': the image's alternative text.
  • 'style_name': (optional) the name of an image style.
  • 'title': (optional) an image title.
  • 'uri': the URI of the item or file.
  • 'maximumEmbedWidth': (optional) a copy of 'maximumEmbedWidth'.
  • 'maximumEmbedHeight': (optional) a copy of 'maximumEmbedHeight'.

Outgoing variables include the above plus:

  • 'image': a theme-ready image description.

    • '#theme': the name of the theme to use (always 'image').
    • '#attributes': a copy of 'attributes'.
    • '#width': the styled image width.
    • '#height': the styled image height.
    • '#alt': the image's alternative text.
    • '#style_name': (optional) the name of an image style.
    • '#title': (optional) an image title.
    • '#uri': (optional) the URI of the styled or original image if it could not be embedded as a data URL.

Template processing loads the named style and computes the style's output image width and height and uses them in the output variables.

Compared to the parent class's template_preprocess_image_style(), this function checks if a styled image is within the maximum embed width/height limits and attempts to load the image to create a data URL. If the image is not available yet (such as a styled image that hasn't been created and cached yet), a file URL is used.

Default template: formatter-suite-image-embed-style.html.twig.

Parameters

array $variables: Returns an associative array of theme variables.

File

./formatter_suite.module, line 396
Implements the principal entry points and hooks for the module.

Code

function template_preprocess_formatter_suite_image_embed_style(array &$variables) {

  // Invoke the image module to process variables. This sets up the 'image'
  // variable with the image's styled width and height, style, title, and
  // URL for links. It also includes a URI for the source image.
  template_preprocess_image_style($variables);

  // Check that the styled image is within our embedding bounds.
  $maximumEmbedWidth = (int) $variables['maximumEmbedWidth'];
  $maximumEmbedHeight = (int) $variables['maximumEmbedHeight'];
  $width = (int) $variables['image']['#width'];
  $height = (int) $variables['image']['#height'];
  if ($maximumEmbedWidth > 0 && $width > $maximumEmbedWidth || $maximumEmbedHeight > 0 && $height > $maximumEmbedHeight) {

    // The styled image is too large for embedding. The parent class has
    // already set things up to use a file URL. Leave things that way.
    return;
  }

  // Get the image style and validate.
  //
  // We explicitly load the style without referring to the "ImageStyle" class
  // so that this code doesn't depend upon that class. This enables the module
  // to be used even when the Image module is not installed (though this
  // function won't be called in that case).
  $sourceUri = $variables['uri'];
  $entityTypeManager = \Drupal::service("entity_type.manager");
  $storage = $entityTypeManager
    ->getStorage('image_style');
  if ($storage === NULL) {

    // The ImageStyle entity type is NOT defined, so the Image module is
    // installed. Without the module, there are no image fields and no
    // opportunities to use this module's image field formatters. And that
    // means no calls to this code. BUT, just in case, let whatever other
    // preprocessors have done continue.
    return;
  }
  $style = $storage
    ->load($variables['style_name']);
  if ($style === NULL || $style
    ->supportsUri($sourceUri) === FALSE) {

    // Either the style won't load or the image at hand is not supported
    // by the style (or the underlying image toolkit). In this case, there
    // is no styled image and the parent class has already set up theme
    // variables to point to the original image. Leave things that way.
    return;
  }

  // Get the URI of the styled image.
  $styledUri = $style
    ->buildUri($sourceUri);

  // Get the real path to the styled image.
  $fileSystem = \Drupal::service('file_system');
  $path = $fileSystem
    ->realpath($styledUri);
  if ($path === FALSE || @file_exists($path) === FALSE) {

    // The file does not exist yet. The image module only creates and caches
    // styled images on the first use, so this image hasn't been used yet.
    //
    // The parent class has already set things up to use a file URL that will
    // trigger creation of the styled image. Leave things that way.
    //
    // On the NEXT use of this image, the file will exist and we can
    // embed it.
    return;
  }

  // Get the file's MIME type. We need this for the data URL.
  //
  // Styling can change the file format of the image, which changes its
  // MIME type. So we need to query the MIME type of the styled image
  // instead of using whatever is saved in the image object.
  $mimeType = \Drupal::service('file.mime_type.guesser')
    ->guess($path);

  // Read the file's raw bytes and base64 encode them as a data URL.
  $data = file_get_contents($path);
  $dataUrl = 'data:' . $mimeType . ';base64,' . base64_encode($data);

  // Set the image's source to be the data URL. To prevent this from
  // being overwritten with the image's URI, delete that URI from the
  // variables.
  $variables['image']['#attributes']['src'] = $dataUrl;
  unset($variables['image']['#uri']);
}