elevatezoomplus-8.x-1.x-dev/src/ElevateZoomPlusManager.php

src/ElevateZoomPlusManager.php
<?php

namespace Drupal\elevatezoomplus;

use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\blazy\BlazyManagerInterface;
use Drupal\elevatezoomplus\Entity\ElevateZoomPlus;

/**
 * Provides ElevateZoom Plus library methods mainly for hooks.
 */
class ElevateZoomPlusManager implements ElevateZoomPlusManagerInterface {

  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'];
  }

  /**
   * {@inheritdoc}
   */
  public function manager() {
    return $this->manager;
  }

  /**
   * {@inheritdoc}
   */
  public function isApplicable(array $settings): bool {
    $obj = $this->manager->verifySafely($settings);
    return $obj->get('elevatezoomplus') || !empty($settings['elevatezoomplus']);
  }

  /**
   * {@inheritdoc}
   *
   * @todo remove some settings after Splick/Splide.
   */
  public function getOptions(array $settings): array {
    $blazies   = $this->manager->verifySafely($settings);
    $id        = $settings['elevatezoomplus'] ?? 'default';
    $id        = $blazies->get('elevatezoomplus') ?: $id;
    $filters   = ['blazy_filter', 'splide_filter', 'slick_filter'];
    $switch    = $settings['media_switch'] ?? '';
    $fallback  = $blazies->get('ui.extras.elevatezoomplus', 'default');
    $plugin_id = $blazies->get('filter.plugin_id');
    $switch    = $blazies->get('switch') ?: $switch;
    $nav       = $blazies->is('nav');
    $is_filter = $plugin_id && in_array($plugin_id, $filters);
    $option_id = $is_filter ? $fallback : $id;
    $optionset = ElevateZoomPlus::loadWithFallback($option_id);
    $options   = $optionset->getSettings(TRUE);

    // If not using Slick/ Splide, provides a static grid gallery.
    if (!$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']);
    }

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function getOptionsetOptions($entity_type): array {
    if (!isset($this->optionsetOptions)) {
      $this->optionsetOptions = $this->manager->getEntityAsOptions($entity_type);
    }
    return $this->optionsetOptions;
  }

  /**
   * {@inheritdoc}
   *
   * @todo use hook_blazy_element_alter(&$element, &$settings) post blazy:2.17.
   */
  public function preRenderBuild(array $element): array {
    $build = $element['#build'];
    unset($element['#build']);

    // Supported themes: Blazy (field|item_list), slick|splide_wrapper,
    // gridstack.
    $settings = [];
    foreach (['blazy', 'build', 'context', 'settings'] as $key) {
      $k = '#' . $key;

      if (isset($build[$k])) {
        // @todo use the second at blazy:3.x when refactored.
        $settings = $build[$k]['#settings'] ?? $build[$k]['settings'] ?? [];
        $settings = ($key == 'build' || $key == 'context')
          ? $settings : $build[$k];
        break;
      }
    }

    // The AJAX class was already excluded at Blazymanager line #505 and passed
    // into #container_attributes below, gone at 2021, likely changed somewhere.
    $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 = $element['#ajax_replace_class'] ?? '';
    if (empty($ajax_class)) {
      if ($classes = ($build['#attributes']['class'] ?? [])) {
        foreach ($classes 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;
  }

  /**
   * {@inheritdoc}
   */
  public function preprocessBlazy(array &$variables): void {
    $settings   = $variables['settings'];
    $blazies    = $settings['blazies'];
    $zoom_url   = $variables['url'];
    $is_nav     = $blazies->is('nav') || !empty($settings['nav']);
    $box_url    = $blazies->get('lightbox.url');
    $multimedia = $blazies->is('multimedia');
    $data_b     = $blazies->use('data_b', TRUE);

    // Support video thumbnail since `url` points to a provider site.
    if ($multimedia && $box_url) {
      $zoom_url = $box_url;
    }

    // Re-use thumbnail style for the stage/ preview image.
    $prefix = $data_b ? 'data-b-' : 'data-';
    $thumb = $variables['attributes'][$prefix . 'thumb'] ?? NULL;
    $stage_url = $thumb ?: $zoom_url;

    // @todo remove post blazy:3.0.9.
    if ($blazies->get('media.type') === 'image') {
      $variables['url_attributes']['class'][] = 'litebox--image';
    }

    // Provides the expected attributes for JS, except for lighboxes which
    // support (local|remote) videos.
    if (!$multimedia) {
      $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, too.
      $id = $this->manager->getHtmlId('elevatezoomplus');
      if ($is_nav) {
        $variables['url_attributes']['class'][] = 'elevatezoomplus';
        $variables['url_attributes']['id'] = $id;
      }
      else {
        $variables['item_attributes']['id'] = $id;
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function attachAlter(array &$load, array $attach): void {
    // @todo more robust dynamic mixed media. Not easy due to no video suports.
    // if (empty($attach['media']) && !empty($attach['bundles'])
    // && in_array('remote_video', $attach['bundles'])) {
    // $load['library'][] = 'blazy/media';
    // }
    $load['drupalSettings']['elevateZoomPlus'] = ElevateZoomPlus::defaultSettings();
    $load['library'][] = 'elevatezoomplus/load';
  }

  /**
   * {@inheritdoc}
   */
  public function buildAlter(array &$build, array $settings): void {
    $this->manager->verifySafely($settings);

    if ($this->isApplicable($settings)) {
      $build = [
        '#theme' => 'elevatezoomplus',
        '#build' => $build,
        '#pre_render' => [[$this, 'preRenderBuild']],
      ];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function formElementAlter(array &$form, array $definition): void {
    $blazies    = $definition['blazies'] ?? NULL;
    $scopes     = $definition['scopes'] ?? NULL;
    $field_type = $definition['field_type'] ?? NULL;
    $settings   = $definition['settings'] ?? [];
    $texts      = ['link', 'string', 'string_long'];
    $no_image   = $definition['no_image_style'] ?? FALSE;

    if ($blazies) {
      $field_type = $scopes->get('field.type') ?: $field_type;
    }
    if ($scopes) {
      $no_image = $scopes->is('no_image_style') || $no_image;
    }

    // Exclude from blazy text formatters, or blazy views grid.
    $applicable = $field_type && !in_array($field_type, $texts);
    if (!$no_image && !isset($settings['grouping'])) {
      $elevatezoomplus = [
        '#type'          => 'select',
        '#title'         => $this->t('ElevateZoom Plus'),
        '#options'       => $this->getOptionsetOptions('elevatezoomplus'),
        '#empty_option'  => $this->t('- None -'),
        '#default_value' => $settings['elevatezoomplus'] ?? '',
        '#description'   => $this->t('Choose an optionset.'),
        '#weight'        => -98.99,
        '#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'] = $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, choose only <b>Image to Elevatezoomplus</b>. Be sure to read <a href=":url">Elevatezoomplus Help</a>.', [
            ':url' => '/admin/help/elevatezoomplus_ui',
          ]);
          if ($this->manager->config('admin_css', 'blazy.settings')) {
            $form['closing']['#attached']['library'][] = 'elevatezoomplus/admin';
          }
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function libraryInfoAlter(array &$libraries, $extension): void {
    $gitdir = 'elevatezoom-plus';
    $dirs = [$gitdir, 'ez-plus'];
    if ($library = $this->manager->getLibrariesPath($dirs)) {
      $ext = is_file($library . '/src/jquery.ez-plus.min.js') ? 'min.js' : 'js';
      $libraries['elevatezoomplus']['js']['/' . $library . '/src/jquery.ez-plus.' . $ext] = ['weight' => -1];

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

      // In case both github and packagist are present, remove github.
      if (!$this->manager->getLibrariesPath($gitdir)) {
        unset($libraries['elevatezoomplus']['js']['/libraries/' . $gitdir . '/src/jquery.ez-plus.js']);
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc