You are here

juicebox.module in Juicebox HTML5 Responsive Image Galleries 8.3

Same filename and directory in other branches
  1. 8.2 juicebox.module
  2. 7.2 juicebox.module
  3. 7 juicebox.module

Module file for Juicebox.

File

juicebox.module
View source
<?php

/**
 * @file
 * Module file for Juicebox.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\juicebox\JuiceboxGalleryInterface;

/**
 * Implements hook_theme().
 */
function juicebox_theme() {
  return [
    // Template for the main Juicebox embed markup.
    'juicebox_embed_markup' => [
      'template' => 'juicebox-embed-markup',
      'file' => 'templates/juicebox.theme.inc',
      'render element' => 'element',
    ],
    // Field template for use with relative-width galleries.
    'field__juicebox_relative_width' => [
      'base hook' => 'field',
    ],
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function juicebox_theme_suggestions_field_alter(array &$suggestions, array $variables) {

  // Some themes (e.g. Bartik) style fields in special ways that breaks
  // Juicebox output. Specifically they target a theme-specific selector,
  // that identifies the field type (e.g. "field-type-image"), with special CSS.
  // This CSS often assumes an inline list of images that have layout/width is
  // being renderd, and apply float or table positioning on the field wrapper.
  // This positioning can make relative width galleries display in very
  // unpredictable ways. To address this we implement our own field template,
  // based on the base core field template, for fields that contains a
  // relative-width Juicebox gallery.
  // @see https://www.drupal.org/node/2625806
  if (isset($variables['element']['#formatter']) && $variables['element']['#formatter'] == 'juicebox_formatter' && isset($variables['element'][0]['#gallery']) && $variables['element'][0]['#gallery'] instanceof JuiceboxGalleryInterface) {
    $options = $variables['element'][0]['#gallery']
      ->getOptions();

    // If the gallery has a "%" char in the width configuration it's a
    // relative-width gallery.
    if (array_key_exists('gallerywidth', $options) && strpos($options['gallerywidth'], '%')) {
      $suggestions[] = 'field__juicebox_relative_width';
    }
  }
}

/**
 * Builds library variable depending on version of library.
 *
 * Library can be in sites/all/libraries/juicebox or /library.
 *
 * param mixed $librarypath
 *   The path to the library.
 *
 * @param mixed $library
 *   The name of the library.
 */
function juicebox_build_library_array($librarypath, &$library) {
  $options = [
    'file' => 'juicebox.js',
    'pattern' => '/Juicebox.([a-zA-Z]+[0-9\\.\\ -]+)/',
    'lines' => 5,
    'cols' => 200,
  ];
  $library['name'] = 'Juicebox';
  $library['vendor url'] = 'http://www.juicebox.net/';
  $library['download url'] = 'http://www.juicebox.net/download/';
  $library['version arguments'] = [
    'file' => 'juicebox.js',
    'pattern' => '/Juicebox.([a-zA-Z]+[0-9\\.\\ -]+)/',
    'lines' => 5,
  ];
  $library['files'] = [
    // Note that we do not want the Juicebox library javascript to be
    // aggregated by Drupal (set preprocess option = FALSE). This is because
    // some supporting library CSS files must be at a specific location
    // RELATIVE to to the main js file. Aggregation breaks this.
    'js' => [
      'juicebox.js' => [
        'preprocess' => FALSE,
        'group' => JS_LIBRARY,
      ],
    ],
  ];
  $library['module'] = 'juicebox';
  $library['machine name'] = 'juicebox';
  $library['path'] = '';
  $library['library path'] = $librarypath;
  $library['disallowed_conf'] = [];
  $library['compatible_mimetypes'] = [
    'image/gif',
    'image/jpeg',
    'image/png',
  ];
  $library['base_languagelist'] = 'Show Thumbnails|Hide Thumbnails|Expand Gallery|Close Gallery|Open Image in New Window';
  $file = DRUPAL_ROOT . $librarypath;
  if (empty($options['file']) || !file_exists($file)) {
    return;
  }
  $file = fopen($file, 'r');
  while ($options['lines'] && ($line = fgets($file, $options['cols']))) {
    if (preg_match($options['pattern'], $line, $version)) {
      $library['version'] = $version[1];
    }
    $options['lines']--;
  }
  fclose($file);
  $pro = FALSE;
  $disallowed_conf = [];
  if (!empty($library['version'])) {

    // Check if this is a Pro version.
    if (stripos($library['version'], "Pro") !== FALSE) {
      $pro = "TRUE";
    }
    $version_number = 0;
    $matches = [];
    preg_match("/[0-9\\.]+[^\\.]\$/u", $library['version'], $matches);
    if (!empty($matches[0])) {
      $version_number = $matches[0];
    }

    // Some options are not available as LITE options < v1.3.
    if (!$pro && version_compare($version_number, '1.3', '<')) {
      $disallowed_conf = array_merge($disallowed_conf, [
        'jlib_textColor',
        'jlib_thumbFrameColor',
        'jlib_useFullscreenExpand',
        'jlib_useThumbDots',
      ]);
    }

    // Multisize features are only available in PRO >= v1.4.
    if (!$pro || version_compare($version_number, '1.4', '<')) {
      $disallowed_conf = array_merge($disallowed_conf, [
        'juicebox_multisize_image_style',
      ]);
    }

    // Set the correct languageList string.
    if (version_compare($version_number, '1.4.0', '>=')) {
      $library['base_languagelist'] .= '|Images';
    }
    if ($pro) {
      $library['base_languagelist'] .= '|Next Image|Previous Image|Play Audio|Pause Audio|Show Information|Hide Information|Start AutoPlay|Stop AutoPlay|AutoPlay ON|AutoPlay OFF|Go Back|Buy this Image|Share on Facebook|Share on Twitter|Share on Google+|Share on Pinterest|Share on Tumblr|of';
      if (version_compare($version_number, '1.5.0', '>=')) {
        $library['base_languagelist'] .= '|Send Email|Download';
      }
    }
  }
  if ($pro) {
    $library['pro'] = "Pro";
  }
  $library['disallowed_conf'] = $disallowed_conf;
  $library['installed'] = TRUE;
  return $library;
}

/**
 * Form validation callback: validate width/height inputs.
 */
function juicebox_element_validate_dimension($element, FormStateInterface $form_state, $form) {
  if (!preg_match('/^[0-9]+?(%|px|em|in|cm|mm|ex|pt|pc)$/u', $element['#value'])) {
    $form_state
      ->setError($element, t('Please ensure that your width and height values are entered in a standard numeric format (such as <strong>100%</strong> or <strong>300px</strong>).'));
  }
}

/**
 * Form validation callback: validate Juicebox configuration options.
 */
function juicebox_element_validate_config($element, FormStateInterface $form_state, $form) {

  // We are looking for input in the format of: optionName="optionValue".
  // The check here is not too strict, it is just meant to catch general
  // formatting issues.
  $custom_options = explode("\n", $element['#value']);
  foreach ($custom_options as $key => $option) {
    $option = trim($option);
    $line_number = $key + 1;
    if (!empty($option) && !preg_match('/^[A-Za-z0-9]+?="[^"]+?"$/u', $option)) {
      $form_state
        ->setError($element, t('One of your manual configuration options appears to be formatted incorrectly. Please check line @line of this field and ensure that you are using the format <strong>optionName="optionValue"</strong> and that all spaces have been removed.', [
        '@line' => $line_number,
      ]));
    }
  }
}

Functions

Namesort descending Description
juicebox_build_library_array Builds library variable depending on version of library.
juicebox_element_validate_config Form validation callback: validate Juicebox configuration options.
juicebox_element_validate_dimension Form validation callback: validate width/height inputs.
juicebox_theme Implements hook_theme().
juicebox_theme_suggestions_field_alter Implements hook_theme_suggestions_HOOK_alter().