You are here

class ElevateZoomPlusManager in ElevateZoom Plus 8

Same name and namespace in other branches
  1. 7 src/ElevateZoomPlusManager.php \Drupal\elevatezoomplus\ElevateZoomPlusManager

Provides ElevateZoom Plus library methods mainly for hooks.

Hierarchy

Expanded class hierarchy of ElevateZoomPlusManager

1 string reference to 'ElevateZoomPlusManager'
elevatezoomplus.services.yml in ./elevatezoomplus.services.yml
elevatezoomplus.services.yml
1 service uses ElevateZoomPlusManager
elevatezoomplus.manager in ./elevatezoomplus.services.yml
Drupal\elevatezoomplus\ElevateZoomPlusManager

File

src/ElevateZoomPlusManager.php, line 14

Namespace

Drupal\elevatezoomplus
View source
class ElevateZoomPlusManager implements TrustedCallbackInterface {
  use StringTranslationTrait;

  /**
   * The blazy manager service.
   *
   * @var \Drupal\blazy\BlazyManagerInterface
   */
  protected $manager;

  /**
   * Static cache for the optionset options.
   *
   * @var array
   */
  protected $optionsetOptions;

  /**
   * Constructs a ElevateZoomPlusManager instance.
   */
  public function __construct(BlazyManagerInterface $manager) {
    $this->manager = $manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function trustedCallbacks() {
    return [
      'preRenderBuild',
    ];
  }

  /**
   * Returns Blazy manager service.
   */
  public function manager() {
    return $this->manager;
  }

  /**
   * Implements hook_library_info_alter().
   */
  public function libraryInfoAlter(&$libraries, $extension) {
    $library = elevatezoomplus_libraries_get_path('elevatezoom-plus') ?: elevatezoomplus_libraries_get_path('ez-plus');
    if ($library) {
      $ext = is_file($library . '/src/jquery.ez-plus.min.js') ? 'min.js' : 'js';
      $libraries['elevatezoomplus']['js']['/' . $library . '/src/jquery.ez-plus.' . $ext] = [
        'weight' => -5,
      ];

      // Due to soft dependencies.
      if ($this->manager
        ->getModuleHandler()
        ->moduleExists('splide')) {
        $libraries['load']['dependencies'][] = 'splide/load';
        $libraries['load']['dependencies'][] = 'splide/nav';
      }
      if ($this->manager
        ->getModuleHandler()
        ->moduleExists('slick')) {
        $libraries['load']['dependencies'][] = 'slick/slick.load';
      }
    }
  }

  /**
   * Checks if the requirements are met.
   */
  public function isApplicable(array $settings) {
    return !empty($settings['elevatezoomplus']) && (!empty($settings['_uri']) || !empty($settings['uri']));
  }

  /**
   * Returns available options for select options.
   *
   * @todo remove if BlazyManager has it.
   */
  public function getOptionsetOptions($entity_type = '') {
    if (!isset($this->optionsetOptions)) {
      $optionsets = [];
      foreach ($this->manager
        ->entityLoadMultiple($entity_type) as $key => $entity) {
        $optionsets[$key] = strip_tags($entity
          ->label());
      }
      $this->optionsetOptions = $optionsets;
    }
    return $this->optionsetOptions;
  }

  /**
   * Implements hook_blazy_form_element_alter().
   */
  public function formElementAlter(array &$form, array $definition = []) {
    $field_type = isset($definition['field_type']) ? $definition['field_type'] : '';
    $settings = $definition['settings'];
    $texts = [
      'link',
      'string',
      'string_long',
    ];
    $applicable = $field_type && !in_array($field_type, $texts);

    // Exclude from blazy text formatters, or blazy views grid.
    if (empty($definition['no_image_style']) && !isset($settings['grouping'])) {
      $elevatezoomplus = [
        '#type' => 'select',
        '#title' => $this
          ->t('ElevateZoom Plus'),
        '#options' => $this
          ->getOptionsetOptions('elevatezoomplus'),
        '#empty_option' => $this
          ->t('- None -'),
        '#default_value' => isset($settings['elevatezoomplus']) ? $settings['elevatezoomplus'] : '',
        '#description' => $this
          ->t('Choose an optionset.'),
        '#weight' => -98.98999999999999,
        '#enforce' => FALSE,
      ];

      // Hooks into Blazy UI to support Blazy Filter.
      if (isset($settings['admin_css'])) {
        $form['extras']['#access'] = TRUE;
        $form['extras']['elevatezoomplus'] = $elevatezoomplus;
        $form['extras']['elevatezoomplus']['#default_value'] = isset($settings['extras']['elevatezoomplus']) ? $settings['extras']['elevatezoomplus'] : '';
        $form['extras']['elevatezoomplus']['#description'] .= ' ' . $this
          ->t('Blazy/Splide/Slick Filter only. Warning! Not working nicely. This needs extra image styles which are lacking with inline images.');
      }
      else {
        if ($applicable) {
          $form['elevatezoomplus'] = $elevatezoomplus;
          $form['elevatezoomplus']['#description'] .= ' ' . $this
            ->t('Requires any lightbox (<b>not: Image to iFrame, Image linked to content, Image rendered</b>) for <b>Media switcher</b> if using Splide/Slick with asNavFor. If not, be sure to choose only <b>Image to Elevatezoomplus</b>.');
          if ($this->manager
            ->configLoad('admin_css', 'blazy.settings')) {
            $form['closing']['#attached']['library'][] = 'elevatezoomplus/admin';
          }
        }
      }
    }
  }

  /**
   * Return the options for the JSON object.
   */
  public function getOptions(array $settings = []) {
    $config = $this->manager
      ->configLoad();
    $fallback = empty($config['extras']['elevatezoomplus']) ? 'default' : $config['extras']['elevatezoomplus'];
    $plugin_id = isset($settings['plugin_id']) ? $settings['plugin_id'] : '';
    $filters = [
      'blazy_filter',
      'splide_filter',
      'slick_filter',
    ];
    $option_id = $plugin_id && in_array($plugin_id, $filters) ? $fallback : $settings['elevatezoomplus'];
    $optionset = ElevateZoomPlus::loadWithFallback($option_id);
    $options = $optionset
      ->getSettings(TRUE);

    // If not using Slick Carousel, provides a static grid gallery.
    if (empty($settings['nav'])) {
      $options['galleryItem'] = '[data-elevatezoomplus-trigger]';
      $options['galleryActiveClass'] = 'is-active';
      $options['gallerySelector'] = '[data-elevatezoomplus-gallery]';
    }
    if (isset($options['zoomWindowPosition']) && is_numeric($options['zoomWindowPosition'])) {
      $options['zoomWindowPosition'] = (int) $options['zoomWindowPosition'];
    }
    if (empty($options['loadingIcon'])) {
      unset($options['loadingIcon']);
    }

    // @todo remove workarounds post modules update.
    $namespace = isset($settings['namespace']) ? $settings['namespace'] : '';
    $behaviors = [];
    if ($namespace) {
      if ($namespace == 'splide') {
        $behaviors = [
          'splide',
          'splideNav',
        ];
      }
      elseif ($namespace == 'slick') {
        $behaviors = [
          'slick',
        ];
      }
    }
    if (isset($settings['media_switch']) && ($settings['media_switch'] = 'media')) {
      $behaviors[] = 'blazyMedia';
    }
    if (isset($settings['lightbox']) && ($lightbox = $settings['lightbox'])) {
      foreach ($this->manager
        ->getLightboxes() as $key) {
        if ($lightbox == $key) {
          switch ($key) {
            case 'colorbox':
              $behaviors[] = 'blazyColorbox';
              break;
            case 'photobox':
              $behaviors[] = 'blazyPhotobox';
              break;
            case 'photoswipe':
              $behaviors[] = 'blazyPhotoSwipe';
              break;
            case 'slick_lightbox':
              $behaviors[] = 'slickLightbox';
              break;
            default:
              $behaviors[] = $key;
              break;
          }
        }
      }
    }
    if ($behaviors) {
      $options['behaviors'] = $behaviors;
    }
    return $options;
  }

  /**
   * Takes over original pre_render to avoid working with early render.
   */
  public function buildAlter(array &$build, $settings = []) {
    if ($this
      ->isApplicable($settings)) {
      $build = [
        '#theme' => 'elevatezoomplus',
        '#build' => $build,
        '#pre_render' => [
          [
            $this,
            'preRenderBuild',
          ],
        ],
      ];
    }
  }

  /**
   * The #pre_render callback: Provides ElevateZoomPlus related contents.
   */
  public function preRenderBuild($element) {
    $build = $element['#build'];
    unset($element['#build']);

    // Supported themes: Blazy (field|item_list), slick_wrapper, gridstack.
    $settings = [];
    foreach ([
      'blazy',
      'build',
      'context',
      'settings',
    ] as $key) {
      if (isset($build['#' . $key])) {
        $settings = isset($build['#' . $key]['settings']) ? $build['#' . $key]['settings'] : [];
        $settings = $key == 'build' || $key == 'context' ? $settings : $build['#' . $key];
        break;
      }
    }

    // The AJAX class was already excluded at Blazymanager line #505 and passed
    // into #container_attributes below, gone at 2021, likely changed somewhere.
    $attributes = isset($element['#container_attributes']) ? (array) $element['#container_attributes'] : [];

    // Preserves the AJAX class for the container, then removes it later for the
    // the theme. This is because product container shares the same attributes
    // array which cause unwanted double AJAX classes.
    // Not available if `Use field template` is checked.
    $ajax_class = isset($element['#ajax_replace_class']) ? $element['#ajax_replace_class'] : '';
    if (empty($ajax_class)) {
      if (isset($build['#attributes'], $build['#attributes']['class'])) {
        foreach ($build['#attributes']['class'] as $key => $class) {
          if (mb_strpos($class, 'product--variation-field--variation') !== FALSE) {
            $attributes['class'][] = $class;
            break;
          }
        }
      }
    }
    else {
      $attributes['class'][] = $ajax_class;
    }
    $settings['ajax_replace_class'] = $ajax_class;
    $element['#settings'] = $settings;
    $element['#attributes'] = $attributes;
    $element['#content'] = $build;
    unset($build);
    return $element;
  }

  /**
   * Implements hook_blazy_attach_alter().
   */
  public function attachAlter(array &$load, $attach = []) {
    $load['drupalSettings']['elevateZoomPlus'] = ElevateZoomPlus::defaultSettings();
    $load['library'][] = 'elevatezoomplus/load';
  }

  /**
   * Overrides variables for theme_blazy().
   */
  public function preprocessBlazy(&$variables) {
    $settings = $variables['settings'];
    $zoom_url = $variables['url'];

    // Support video thumbnail since `url` points to a provider site.
    if ($settings['type'] == 'video' && !empty($settings['box_url'])) {
      $zoom_url = $settings['box_url'];
    }

    // Re-use thumbnail style for the stage/ preview image.
    $stage_url = empty($variables['attributes']['data-thumb']) ? $zoom_url : $variables['attributes']['data-thumb'];

    // Provides the expected attributes for JS.
    $variables['url_attributes']['data-image'] = $stage_url;
    $variables['url_attributes']['data-zoom-image'] = $zoom_url;

    // If using Slick asNavFor, make the litebox link as a zoom trigger as well.
    $id = Blazy::getHtmlId('elevatezoomplus');
    if (!empty($settings['nav'])) {
      $variables['url_attributes']['class'][] = 'elevatezoomplus';
      $variables['url_attributes']['id'] = $id;
    }
    else {
      $variables['item_attributes']['id'] = $id;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ElevateZoomPlusManager::$manager protected property The blazy manager service.
ElevateZoomPlusManager::$optionsetOptions protected property Static cache for the optionset options.
ElevateZoomPlusManager::attachAlter public function Implements hook_blazy_attach_alter().
ElevateZoomPlusManager::buildAlter public function Takes over original pre_render to avoid working with early render.
ElevateZoomPlusManager::formElementAlter public function Implements hook_blazy_form_element_alter().
ElevateZoomPlusManager::getOptions public function Return the options for the JSON object.
ElevateZoomPlusManager::getOptionsetOptions public function Returns available options for select options.
ElevateZoomPlusManager::isApplicable public function Checks if the requirements are met.
ElevateZoomPlusManager::libraryInfoAlter public function Implements hook_library_info_alter().
ElevateZoomPlusManager::manager public function Returns Blazy manager service.
ElevateZoomPlusManager::preprocessBlazy public function Overrides variables for theme_blazy().
ElevateZoomPlusManager::preRenderBuild public function The #pre_render callback: Provides ElevateZoomPlus related contents.
ElevateZoomPlusManager::trustedCallbacks public static function Lists the trusted callbacks provided by the implementing class. Overrides TrustedCallbackInterface::trustedCallbacks
ElevateZoomPlusManager::__construct public function Constructs a ElevateZoomPlusManager instance.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
TrustedCallbackInterface::THROW_EXCEPTION constant Untrusted callbacks throw exceptions.
TrustedCallbackInterface::TRIGGER_SILENCED_DEPRECATION constant Untrusted callbacks trigger silenced E_USER_DEPRECATION errors.
TrustedCallbackInterface::TRIGGER_WARNING constant Untrusted callbacks trigger E_USER_WARNING errors.