You are here

class SlickSkinManager in Slick Carousel 8.2

Provides Slick skin manager.

Hierarchy

Expanded class hierarchy of SlickSkinManager

1 string reference to 'SlickSkinManager'
slick.services.yml in ./slick.services.yml
slick.services.yml
1 service uses SlickSkinManager
slick.skin_manager in ./slick.services.yml
Drupal\slick\SlickSkinManager

File

src/SlickSkinManager.php, line 18

Namespace

Drupal\slick
View source
class SlickSkinManager extends DefaultPluginManager implements SlickSkinManagerInterface, MapperInterface {
  use StringTranslationTrait;

  /**
   * The app root.
   *
   * @var \SplString
   */
  protected $root;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $config;

  /**
   * Static cache for the skin definition.
   *
   * @var array
   */
  protected $skinDefinition;

  /**
   * Static cache for the skins by group.
   *
   * @var array
   */
  protected $skinsByGroup;

  /**
   * The library info definition.
   *
   * @var array
   */
  protected $libraryInfoBuild;

  /**
   * The easing library path.
   *
   * @var string|bool
   */
  protected $easingPath;

  /**
   * The slick library path.
   *
   * @var string|bool
   */
  protected $slickPath;

  /**
   * The breaking change: Slick 1.9.0, or Accessible Slick.
   *
   * @var bool
   */
  protected $isBreaking;

  /**
   * {@inheritdoc}
   */
  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $root, ConfigFactoryInterface $config) {
    parent::__construct('Plugin/slick', $namespaces, $module_handler, SlickSkinPluginInterface::class, 'Drupal\\slick\\Annotation\\SlickSkin');
    $this->root = $root;
    $this->config = $config;
    $this
      ->alterInfo('slick_skin_info');
    $this
      ->setCacheBackend($cache_backend, 'slick_skin_plugins');
  }

  /**
   * Returns the supported skins.
   */
  public function getConstantSkins() {
    return [
      'browser',
      'lightbox',
      'overlay',
      'main',
      'thumbnail',
      'arrows',
      'dots',
      'widget',
    ];
  }

  /**
   * Returns slick config shortcut.
   */
  public function config($key = '', $settings = 'slick.settings') {
    return $this->config
      ->get($settings)
      ->get($key);
  }

  /**
   * Returns cache backend service.
   */
  public function getCache() {
    return $this->cacheBackend;
  }

  /**
   * Returns app root.
   */
  public function root() {
    return $this->root;
  }

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

  /**
   * {@inheritdoc}
   */
  public function loadMultiple() {
    $skins = [];
    foreach ($this
      ->getDefinitions() as $definition) {
      array_push($skins, $this
        ->createInstance($definition['id']));
    }
    return $skins;
  }

  /**
   * Returns slick skins registered via SlickSkin plugin and or defaults.
   */
  public function getSkins() {
    if (!isset($this->skinDefinition)) {
      $cid = 'slick_skins_data';
      if ($cache = $this->cacheBackend
        ->get($cid)) {
        $this->skinDefinition = $cache->data;
      }
      else {
        $methods = [
          'skins',
          'arrows',
          'dots',
        ];
        $skins = $items = [];
        foreach ($this
          ->loadMultiple() as $skin) {
          foreach ($methods as $method) {
            $items[$method] = $skin
              ->{$method}();
          }
          $skins = NestedArray::mergeDeep($skins, $items);
        }

        // @todo remove for the new plugin system at slick:8.x-3.0.
        $disabled = $this
          ->config('disable_old_skins');
        if (empty($disabled)) {
          if ($old_skins = $this
            ->buildSkins($methods)) {
            $skins = NestedArray::mergeDeep($old_skins, $skins);
          }
        }
        $count = isset($items['skins']) ? count($items['skins']) : count($items);
        $tags = Cache::buildTags($cid, [
          'count:' . $count,
        ]);
        $this->cacheBackend
          ->set($cid, $skins, Cache::PERMANENT, $tags);
        $this->skinDefinition = $skins;
      }
    }
    return $this->skinDefinition;
  }

  /**
   * Returns available slick skins by group.
   */
  public function getSkinsByGroup($group = '', $option = FALSE) {
    if (!isset($this->skinsByGroup[$group])) {
      $skins = $groups = $ungroups = [];
      $nav_skins = in_array($group, [
        'arrows',
        'dots',
      ]);
      $defined_skins = $nav_skins ? $this
        ->getSkins()[$group] : $this
        ->getSkins()['skins'];
      foreach ($defined_skins as $skin => $properties) {
        $item = $option ? strip_tags($properties['name']) : $properties;
        if (!empty($group)) {
          if (isset($properties['group'])) {
            if ($properties['group'] != $group) {
              continue;
            }
            $groups[$skin] = $item;
          }
          elseif (!$nav_skins) {
            $ungroups[$skin] = $item;
          }
        }
        $skins[$skin] = $item;
      }
      $this->skinsByGroup[$group] = $group ? array_merge($ungroups, $groups) : $skins;
    }
    return $this->skinsByGroup[$group];
  }

  /**
   * Implements hook_library_info_build().
   */
  public function libraryInfoBuild() {
    if (!isset($this->libraryInfoBuild)) {
      if ($this
        ->config('library') == 'accessible-slick') {
        $libraries['slick.css'] = [
          'dependencies' => [
            'slick/accessible-slick',
          ],
          'css' => [
            'theme' => [
              '/libraries/accessible-slick/slick/accessible-slick-theme.min.css' => [
                'weight' => -2,
              ],
            ],
          ],
        ];
      }
      else {
        $libraries['slick.css'] = [
          'dependencies' => [
            'slick/slick',
          ],
          'css' => [
            'theme' => [
              '/libraries/slick/slick/slick-theme.css' => [
                'weight' => -2,
              ],
            ],
          ],
        ];
      }
      foreach ($this
        ->getConstantSkins() as $group) {
        if ($skins = $this
          ->getSkinsByGroup($group)) {
          foreach ($skins as $key => $skin) {
            $provider = isset($skin['provider']) ? $skin['provider'] : 'slick';
            $id = $provider . '.' . $group . '.' . $key;
            foreach ([
              'css',
              'js',
              'dependencies',
            ] as $property) {
              if (isset($skin[$property]) && is_array($skin[$property])) {
                $libraries[$id][$property] = $skin[$property];
              }
            }
          }
        }
      }
      $this->libraryInfoBuild = $libraries;
    }
    return $this->libraryInfoBuild;
  }

  /**
   * Provides slick skins and libraries.
   */
  public function attach(array &$load, array $attach = []) {
    if (!empty($attach['lazy'])) {
      $load['library'][] = 'blazy/loading';
    }

    // Load optional easing library.
    if ($this
      ->getEasingPath()) {
      $load['library'][] = 'slick/slick.easing';
    }
    if (!empty($attach['_vanilla'])) {
      $load['library'][] = 'slick/vanilla';
    }

    // Allows Slick initializer to be disabled by a special flag _unload.
    if (empty($attach['_unload'])) {
      $load['library'][] = 'slick/slick.load';
    }
    else {
      if ($this
        ->config('slick_css')) {
        $load['library'][] = 'slick/slick.css';
      }
    }
    foreach ([
      'colorbox',
      'mousewheel',
    ] as $component) {
      if (!empty($attach[$component])) {
        $load['library'][] = 'slick/slick.' . $component;
      }
    }
    if (!empty($attach['skin'])) {
      $this
        ->attachSkin($load, $attach);
    }

    // Attach default JS settings to allow responsive displays have a lookup,
    // excluding wasted/trouble options, e.g.: PHP string vs JS object.
    $excludes = explode(' ', 'mobileFirst appendArrows appendDots asNavFor prevArrow nextArrow respondTo pauseIcon playIcon');
    $excludes = array_combine($excludes, $excludes);
    $load['drupalSettings']['slick'] = array_diff_key(Slick::defaultSettings(), $excludes);
  }

  /**
   * Provides skins only if required.
   */
  public function attachSkin(array &$load, $attach = []) {
    if ($this
      ->config('slick_css')) {
      $load['library'][] = 'slick/slick.css';
    }
    if ($this
      ->config('module_css', 'slick.settings')) {
      $load['library'][] = 'slick/slick.theme';
    }
    if (!empty($attach['thumbnail_effect'])) {
      $load['library'][] = 'slick/slick.thumbnail.' . $attach['thumbnail_effect'];
    }
    if (!empty($attach['down_arrow'])) {
      $load['library'][] = 'slick/slick.arrow.down';
    }
    foreach ($this
      ->getConstantSkins() as $group) {
      $skin = $group == 'main' ? $attach['skin'] : (isset($attach['skin_' . $group]) ? $attach['skin_' . $group] : '');
      if (!empty($skin)) {
        $skins = $this
          ->getSkinsByGroup($group);
        $provider = isset($skins[$skin]['provider']) ? $skins[$skin]['provider'] : 'slick';
        $load['library'][] = 'slick/' . $provider . '.' . $group . '.' . $skin;
      }
    }
  }

  /**
   * Returns easing library path if available, else FALSE.
   */
  public function getEasingPath() {
    if (!isset($this->easingPath)) {
      if (slick_libraries_get_path('easing') || slick_libraries_get_path('jquery.easing')) {
        $library_easing = slick_libraries_get_path('easing') ?: slick_libraries_get_path('jquery.easing');
        if ($library_easing) {
          $easing_path = $library_easing . '/jquery.easing.min.js';

          // Composer via bower-asset puts the library within `js` directory.
          if (!is_file($easing_path)) {
            $easing_path = $library_easing . '/js/jquery.easing.min.js';
          }
        }
      }
      else {
        if (is_file($this->root . '/libraries/easing/jquery.easing.min.js')) {
          $easing_path = 'libraries/easing/jquery.easing.min.js';
        }
      }
      $this->easingPath = isset($easing_path) ? $easing_path : FALSE;
    }
    return $this->easingPath;
  }

  /**
   * Returns slick library path if available, else FALSE.
   */
  public function getSlickPath() {
    if (!isset($this->slickPath)) {
      if ($this
        ->config('library') == 'accessible-slick') {
        $library_path = slick_libraries_get_path('accessible-slick');
        if (!$library_path) {
          $path = 'libraries/accessible-slick';
        }
      }
      else {
        $library_path = slick_libraries_get_path('slick-carousel') ?: slick_libraries_get_path('slick');
        if (!$library_path) {
          $path = 'libraries/slick-carousel';
          if (!is_file($this->root . '/' . $path . '/slick/slick.min.js')) {
            $path = 'libraries/slick';
          }
        }
      }
      if (isset($path) && is_file($this->root . '/' . $path . '/slick/slick.min.js')) {
        $library_path = $path;
      }
      $this->slickPath = $library_path;
    }
    return $this->slickPath;
  }

  /**
   * Implements hook_library_info_alter().
   */
  public function libraryInfoAlter(&$libraries, $extension) {
    if ($library_path = $this
      ->getSlickPath()) {
      if ($this
        ->config('library') == 'accessible-slick') {
        $libraries['accessible-slick']['js'] = [
          '/' . $library_path . '/slick/slick.min.js' => [
            'weight' => -3,
          ],
        ];
        $libraries['accessible-slick']['css']['base'] = [
          '/' . $library_path . '/slick/slick.min.css' => [],
        ];
        $libraries['slick.css']['css']['theme'] = [
          '/' . $library_path . '/slick/accessible-slick-theme.min.css' => [
            'weight' => -2,
          ],
        ];
        $libraries_to_alter = [
          'slick.load',
          'slick.colorbox',
          'vanilla',
        ];
        foreach ($libraries_to_alter as $library_name) {
          $key = array_search('slick/slick', $libraries[$library_name]['dependencies']);
          $libraries[$library_name]['dependencies'][$key] = 'slick/accessible-slick';
        }
      }
      else {
        $libraries['slick']['js'] = [
          '/' . $library_path . '/slick/slick.min.js' => [
            'weight' => -3,
          ],
        ];
        $libraries['slick']['css']['base'] = [
          '/' . $library_path . '/slick/slick.css' => [],
        ];
        $libraries['slick.css']['css']['theme'] = [
          '/' . $library_path . '/slick/slick-theme.css' => [
            'weight' => -2,
          ],
        ];
      }
    }
    if ($library_easing = $this
      ->getEasingPath()) {
      $libraries['slick.easing']['js'] = [
        '/' . $library_easing => [
          'weight' => -4,
        ],
      ];
    }
    $library_mousewheel = slick_libraries_get_path('mousewheel') ?: slick_libraries_get_path('jquery-mousewheel');
    if ($library_mousewheel) {
      $libraries['slick.mousewheel']['js'] = [
        '/' . $library_mousewheel . '/jquery.mousewheel.min.js' => [
          'weight' => -4,
        ],
      ];
    }
  }

  /**
   * Check for breaking libraries: Slick 1.9.0, or Accessible Slick.
   */
  public function isBreaking() {
    if (!isset($this->isBreaking)) {
      $this->isBreaking = FALSE;
      if ($this
        ->config('library') == 'accessible-slick') {
        $this->isBreaking = TRUE;
      }
      else {

        // The master reverted from 1.8.1 - 1.9.0 to 1.8.0. This is for old
        // downloads. See https://github.com/kenwheeler/slick/pull/3688
        // @todo Remove after another check.
        if ($path = $this
          ->getSlickPath()) {
          if ($content = \file_get_contents($this->root . '/' . $path . '/package.json')) {
            $this->isBreaking = strpos($content, '"version": "1.9.0"') !== FALSE || strpos($content, '"version": "1.8.1"') !== FALSE;
          }
        }
      }
    }
    return $this->isBreaking;
  }

  /**
   * Collects defined skins as registered via hook_MODULE_NAME_skins_info().
   *
   * This deprecated is adopted from BlazyManager to allow its removal anytime.
   *
   * @todo deprecate and remove at slick:3.x+.
   * @see https://www.drupal.org/node/2233261
   * @see https://www.drupal.org/node/3105670
   */
  private function buildSkins(array $methods = []) {
    $skin_class = '\\Drupal\\slick\\SlickSkin';
    $classes = $this->moduleHandler
      ->invokeAll('slick_skins_info');
    $classes = array_merge([
      $skin_class,
    ], $classes);
    $items = $skins = [];
    foreach ($classes as $class) {
      if (class_exists($class)) {
        $reflection = new \ReflectionClass($class);
        if ($reflection
          ->implementsInterface($skin_class . 'Interface')) {
          $skin = new $class();
          foreach ($methods as $method) {
            $items[$method] = method_exists($skin, $method) ? $skin
              ->{$method}() : [];
          }
        }
      }
      $skins = NestedArray::mergeDeep($skins, $items);
    }
    return $skins;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DefaultPluginManager::$additionalAnnotationNamespaces protected property Additional namespaces the annotation discovery mechanism should scan for annotation definitions.
DefaultPluginManager::$alterHook protected property Name of the alter hook if one should be invoked.
DefaultPluginManager::$cacheKey protected property The cache key.
DefaultPluginManager::$cacheTags protected property An array of cache tags to use for the cached definitions.
DefaultPluginManager::$defaults protected property A set of defaults to be referenced by $this->processDefinition() if additional processing of plugins is necessary or helpful for development purposes. 9
DefaultPluginManager::$moduleHandler protected property The module handler to invoke the alter hook. 1
DefaultPluginManager::$namespaces protected property An object that implements \Traversable which contains the root paths keyed by the corresponding namespace to look for plugin implementations.
DefaultPluginManager::$pluginDefinitionAnnotationName protected property The name of the annotation that contains the plugin definition.
DefaultPluginManager::$pluginInterface protected property The interface each plugin should implement. 1
DefaultPluginManager::$subdir protected property The subdirectory within a namespace to look for plugins, or FALSE if the plugins are in the top level of the namespace.
DefaultPluginManager::alterDefinitions protected function Invokes the hook to alter the definitions if the alter hook is set. 1
DefaultPluginManager::alterInfo protected function Sets the alter hook name.
DefaultPluginManager::clearCachedDefinitions public function Clears static and persistent plugin definition caches. Overrides CachedDiscoveryInterface::clearCachedDefinitions 5
DefaultPluginManager::extractProviderFromDefinition protected function Extracts the provider from a plugin definition.
DefaultPluginManager::findDefinitions protected function Finds plugin definitions. 7
DefaultPluginManager::fixContextAwareDefinitions private function Fix the definitions of context-aware plugins.
DefaultPluginManager::getCacheContexts public function The cache contexts associated with this object. Overrides CacheableDependencyInterface::getCacheContexts
DefaultPluginManager::getCachedDefinitions protected function Returns the cached plugin definitions of the decorated discovery class.
DefaultPluginManager::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyInterface::getCacheMaxAge
DefaultPluginManager::getCacheTags public function The cache tags associated with this object. Overrides CacheableDependencyInterface::getCacheTags
DefaultPluginManager::getDefinitions public function Gets the definition of all plugins for this type. Overrides DiscoveryTrait::getDefinitions 2
DefaultPluginManager::getDiscovery protected function Gets the plugin discovery. Overrides PluginManagerBase::getDiscovery 12
DefaultPluginManager::getFactory protected function Gets the plugin factory. Overrides PluginManagerBase::getFactory
DefaultPluginManager::processDefinition public function Performs extra processing on plugin definitions. 13
DefaultPluginManager::providerExists protected function Determines if the provider of a definition exists. 3
DefaultPluginManager::setCacheBackend public function Initialize the cache backend.
DefaultPluginManager::setCachedDefinitions protected function Sets a cache of plugin definitions for the decorated discovery class.
DefaultPluginManager::useCaches public function Disable the use of caches. Overrides CachedDiscoveryInterface::useCaches 1
DiscoveryCachedTrait::$definitions protected property Cached definitions array. 1
DiscoveryCachedTrait::getDefinition public function Overrides DiscoveryTrait::getDefinition 3
DiscoveryTrait::doGetDefinition protected function Gets a specific plugin definition.
DiscoveryTrait::hasDefinition public function
PluginManagerBase::$discovery protected property The object that discovers plugins managed by this manager.
PluginManagerBase::$factory protected property The object that instantiates plugins managed by this manager.
PluginManagerBase::$mapper protected property The object that returns the preconfigured plugin instance appropriate for a particular runtime condition.
PluginManagerBase::createInstance public function Creates a pre-configured instance of a plugin. Overrides FactoryInterface::createInstance 12
PluginManagerBase::getInstance public function Gets a preconfigured instance of a plugin. Overrides MapperInterface::getInstance 7
PluginManagerBase::handlePluginNotFound protected function Allows plugin managers to specify custom behavior if a plugin is not found. 1
SlickSkinManager::$config protected property The config factory.
SlickSkinManager::$easingPath protected property The easing library path.
SlickSkinManager::$isBreaking protected property The breaking change: Slick 1.9.0, or Accessible Slick.
SlickSkinManager::$libraryInfoBuild protected property The library info definition.
SlickSkinManager::$root protected property The app root.
SlickSkinManager::$skinDefinition protected property Static cache for the skin definition.
SlickSkinManager::$skinsByGroup protected property Static cache for the skins by group.
SlickSkinManager::$slickPath protected property The slick library path.
SlickSkinManager::attach public function Provides slick skins and libraries.
SlickSkinManager::attachSkin public function Provides skins only if required.
SlickSkinManager::buildSkins private function Collects defined skins as registered via hook_MODULE_NAME_skins_info().
SlickSkinManager::config public function Returns slick config shortcut.
SlickSkinManager::getCache public function Returns cache backend service.
SlickSkinManager::getConstantSkins public function Returns the supported skins.
SlickSkinManager::getEasingPath public function Returns easing library path if available, else FALSE.
SlickSkinManager::getSkins public function Returns slick skins registered via SlickSkin plugin and or defaults.
SlickSkinManager::getSkinsByGroup public function Returns available slick skins by group.
SlickSkinManager::getSlickPath public function Returns slick library path if available, else FALSE.
SlickSkinManager::isBreaking public function Check for breaking libraries: Slick 1.9.0, or Accessible Slick.
SlickSkinManager::libraryInfoAlter public function Implements hook_library_info_alter().
SlickSkinManager::libraryInfoBuild public function Implements hook_library_info_build().
SlickSkinManager::load public function Returns an instance of a plugin by given plugin id. Overrides SlickSkinManagerInterface::load
SlickSkinManager::loadMultiple public function
SlickSkinManager::root public function Returns app root.
SlickSkinManager::__construct public function Creates the discovery object. Overrides DefaultPluginManager::__construct
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.
UseCacheBackendTrait::$cacheBackend protected property Cache backend instance.
UseCacheBackendTrait::$useCaches protected property Flag whether caches should be used or skipped.
UseCacheBackendTrait::cacheGet protected function Fetches from the cache backend, respecting the use caches flag. 1
UseCacheBackendTrait::cacheSet protected function Stores data in the persistent cache, respecting the use caches flag.