You are here

textimage.module in Textimage 8.3

Textimage - Provides text to image manipulations.

File

textimage.module
View source
<?php

/**
 * @file
 * Textimage - Provides text to image manipulations.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\image\ImageStyleInterface;

/**
 * Implements hook_help().
 */
function textimage_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'textimage.settings':
      $output = '<p>';
      $output .= t('Textimage provides integration with the <a href="@image_effects_url">Image effects</a> module to generate images with overlaid text.', [
        '@image_effects_url' => 'https://www.drupal.org/project/image_effects',
      ]);
      $output .= ' ' . t('Use <a href="@image">Image styles</a> features to create Image styles. The \'Text overlay\' image effect must be used to specifiy the text appearance on the generated image.', [
        '@image' => Url::fromRoute('entity.image_style.collection'),
      ]);
      $output .= ' ' . t('On the edit image style form, a "Textimage options" section allows selecting Textimage-specific options for the style.');
      $output .= '</p>';
      return $output;
  }
}

/**
 * Implements hook_theme().
 */
function textimage_theme() {
  $theme = [
    // Format a textimage.
    'textimage_formatter' => [
      'variables' => [
        'item' => NULL,
        'uri' => NULL,
        'width' => NULL,
        'height' => NULL,
        'alt' => '',
        'title' => '',
        'attributes' => [],
        'image_container_attributes' => [],
        'anchor_url' => NULL,
      ],
    ],
  ];
  return $theme;
}

/**
 * Implements hook_file_download().
 *
 * Control the access to files underneath the textimage directories.
 */
function textimage_file_download($uri) {
  $path = file_uri_target($uri);

  // Private file access for image style derivatives.
  if (strpos($path, 'textimage') === 0) {

    // Check that the file exists and is an image.
    $image = \Drupal::service('image.factory')
      ->get($uri);
    if ($image
      ->isValid()) {
      return [
        // Send headers describing the image's size, and MIME-type...
        'Content-Type' => $image
          ->getMimeType(),
        'Content-Length' => $image
          ->getFileSize(),
      ];
    }
    return -1;
  }
  return NULL;
}

/**
 * Implements hook_cache_flush().
 */
function textimage_cache_flush() {
  return [
    'textimage',
  ];
}

/**
 * Implements hook_cron().
 */
function textimage_cron() {

  // Remove temporary, uncached, image files in all available schemes.
  $wrappers = \Drupal::service('stream_wrapper_manager')
    ->getWrappers(StreamWrapperInterface::WRITE_VISIBLE);
  foreach ($wrappers as $wrapper => $wrapper_data) {
    if (file_exists($directory = \Drupal::service('textimage.factory')
      ->getStoreUri('/temp', $wrapper))) {
      if (file_unmanaged_delete_recursive($directory)) {
        \Drupal::service('textimage.logger')
          ->notice('Textimage temporary image files removed.');
      }
      else {
        \Drupal::service('textimage.logger')
          ->error('Textimage could not remove temporary image files.');
      }
    }
  }
}

/**
 * Implements hook_token_info().
 */
function textimage_token_info() {
  $type = [
    'name' => t('Textimage'),
    'description' => t('Tokens related to Textimage'),
    'needs-data' => 'node',
  ];
  $tokens = [
    'uri' => [
      'name' => t("URI"),
      'description' => t("The URI(s) of a Textimage generated for a node's field. Use like <strong>[textimage:uri:field{:display}{:sequence}]</strong>, where:<br/><strong>field</strong> is the machine name of the field for which the Textimage is generated (e.g. body or field_xxxx);<br/><strong>display</strong> is an optional indication of the display view mode (e.g. default, full, teaser, etc.); 'default' is used if not specified; <br/><strong>sequence</strong> is an optional indication of the URI to return if Textimage produces more images for the same field (like e.g. in a multi-value Image field); if not specified, a comma-delimited string of all the URIs generated will be returned."),
      'dynamic' => TRUE,
    ],
    'url' => [
      'name' => t("URL"),
      'description' => t("The URL(s) of a Textimage generated for a node's field. Use like <strong>[textimage:url:field{:display}{:sequence}]</strong>, where:<br/><strong>field</strong> is the machine name of the field for which the Textimage is generated (e.g. body or field_xxxx);<br/><strong>display</strong> is an optional indication of the display view mode (e.g. default, full, teaser, etc.); 'default' is used if not specified; <br/><strong>sequence</strong> is an optional indication of the URL to return if Textimage produces more images for the same field (like e.g. in a multi-value Image field); if not specified, a comma-delimited string of all the URLs generated will be returned."),
      'dynamic' => TRUE,
    ],
  ];
  return [
    'types' => [
      'textimage' => $type,
    ],
    'tokens' => [
      'textimage' => $tokens,
    ],
  ];
}

/**
 * Implements hook_tokens().
 */
function textimage_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {

  // Jumps out if not processing textimage tokens.
  if ($type != 'textimage') {
    return [];
  }

  // Jumps out with a warning if node is not available.
  // @todo Another entity may be tokenised.
  if (!isset($data['node'])) {
    \Drupal::service('textimage.logger')
      ->warning('Textimage token(s) @tokens_list could not be resolved as no information about the context was available.', [
      '@tokens_list' => implode(', ', $tokens),
    ]);
    return [];
  }

  // Process tokens.
  $replacements = \Drupal::service('textimage.factory')
    ->processTokens('url', $tokens, $data, $bubbleable_metadata);
  $replacements += \Drupal::service('textimage.factory')
    ->processTokens('uri', $tokens, $data, $bubbleable_metadata);
  return $replacements;
}

/**
 * Implements hook_image_style_flush().
 */
function textimage_image_style_flush($style) {

  // Manage the textimage part of image style flushing.
  \Drupal::service('textimage.factory')
    ->flushStyle($style);
}

/**
 * Implements hook_image_style_presave().
 *
 * Deals with Textimage third party settings.
 */
function textimage_image_style_presave(ImageStyleInterface $style) {

  // If Textimage TPSs are not yet set, set defaults.
  if (!in_array('textimage', $style
    ->getThirdPartyProviders())) {
    $style
      ->setThirdPartySetting('textimage', 'uri_scheme', \Drupal::service('config.factory')
      ->get('system.file')
      ->get('default_scheme'));
  }
}

/**
 * Make alterations to the core 'image_style_form' form.
 *
 * A fieldset is added if the image style is Textimage relevant.
 */
function textimage_form_image_style_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $image_style = $form_state
    ->getFormObject()
    ->getEntity();
  $form['textimage_options'] = [
    '#type' => 'details',
    '#weight' => 10,
    '#tree' => TRUE,
    '#open' => FALSE,
    '#title' => t('Textimage options'),
    '#description' => t('Define Textimage options specific for this image style.'),
  ];

  // Define file storage wrapper used for the style images.
  $scheme_options = \Drupal::service('stream_wrapper_manager')
    ->getNames(StreamWrapperInterface::WRITE_VISIBLE);
  $form['textimage_options']['uri_scheme'] = [
    '#type' => 'radios',
    '#options' => $scheme_options,
    '#title' => t('Image destination'),
    '#description' => t('Select where Textimage image files should be stored. Private file storage has significantly more overhead than public files, but allows access restriction.'),
    '#default_value' => $image_style
      ->getThirdPartySetting('textimage', 'uri_scheme', \Drupal::service('config.factory')
      ->get('system.file')
      ->get('default_scheme')),
  ];

  // Adds a validate handler to deal with textimage options.
  $form['#validate'][] = '_textimage_form_image_style_form_validate';
}

/**
 * Submit handler to deal with the altered 'image_style_form' form.
 */
function _textimage_form_image_style_form_validate($form, FormStateInterface $form_state) {
  $image_style = $form_state
    ->getFormObject()
    ->getEntity();
  $image_style
    ->setThirdPartySetting('textimage', 'uri_scheme', $form_state
    ->getValue([
    'textimage_options',
    'uri_scheme',
  ]));
}

/**
 * Prepares variables to get a Textimage from text.
 *
 * Default template: textimage-formatter.html.twig.
 */
function template_preprocess_textimage_formatter(&$variables) {

  // Render only if the image URI is passed in.
  if ($image_uri = $variables['uri']) {

    // Get alt and title from field item if missing from variables.
    if (!$variables['title'] && $variables['item']) {
      $variables['title'] = $variables['item']
        ->getValue()['title'];
    }
    if (!$variables['alt'] && $variables['item']) {
      $variables['alt'] = $variables['item']
        ->getValue()['alt'];
    }

    // Build anchor link data if needed.
    if ($variables['anchor_url']) {
      if (is_string($variables['anchor_url'])) {
        $href = $variables['anchor_url'];
      }
      else {
        $href = $variables['anchor_url']
          ->toString();
      }
      $variables['anchor_attributes'] = new Attribute([
        'title' => $variables['title'],
        'href' => $href,
      ]);
    }

    // Build image container attributes if needed.
    if (!empty($variables['image_container_attributes'])) {
      $variables['image_container_attributes'] = new Attribute($variables['image_container_attributes']);
    }

    // Get the <img>.
    $variables['image'] = [
      '#theme' => 'image__textimage',
      '#uri' => $image_uri,
      '#width' => $variables['width'],
      '#height' => $variables['height'],
      '#attributes' => $variables['attributes'],
    ];
    if (!empty($variables['title'])) {
      $variables['image']['#title'] = $variables['title'];
    }
    if (!empty($variables['alt'])) {
      $variables['image']['#alt'] = $variables['alt'];
    }
  }
}

Functions

Namesort descending Description
template_preprocess_textimage_formatter Prepares variables to get a Textimage from text.
textimage_cache_flush Implements hook_cache_flush().
textimage_cron Implements hook_cron().
textimage_file_download Implements hook_file_download().
textimage_form_image_style_form_alter Make alterations to the core 'image_style_form' form.
textimage_help Implements hook_help().
textimage_image_style_flush Implements hook_image_style_flush().
textimage_image_style_presave Implements hook_image_style_presave().
textimage_theme Implements hook_theme().
textimage_tokens Implements hook_tokens().
textimage_token_info Implements hook_token_info().
_textimage_form_image_style_form_validate Submit handler to deal with the altered 'image_style_form' form.