View source
<?php
namespace Drupal\slick;
use Drupal\Component\Utility\NestedArray;
use Drupal\slick\Entity\Slick;
use Drupal\blazy\Blazy;
use Drupal\blazy\BlazyManagerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
class SlickManager extends BlazyManagerBase implements SlickManagerInterface {
protected $skinManager;
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance
->setSkinManager($container
->get('slick.skin_manager'));
return $instance;
}
public static function trustedCallbacks() {
return [
'preRenderSlick',
'preRenderSlickWrapper',
];
}
public function skinManager() {
return $this->skinManager;
}
public function setSkinManager(SlickSkinManagerInterface $skin_manager) {
$this->skinManager = $skin_manager;
return $this;
}
public function attach(array $attach = []) {
$load = parent::attach($attach);
$this->skinManager
->attach($load, $attach);
$this->moduleHandler
->alter('slick_attach', $load, $attach);
return $load;
}
public function slick(array $build = []) {
foreach (SlickDefault::themeProperties() as $key) {
$build[$key] = isset($build[$key]) ? $build[$key] : [];
}
return empty($build['items']) ? [] : [
'#theme' => 'slick',
'#items' => [],
'#build' => $build,
'#pre_render' => [
[
$this,
'preRenderSlick',
],
],
];
}
protected function prepareAttributes(array $build = []) {
$settings = $build['settings'];
$attributes = isset($build['attributes']) ? $build['attributes'] : [];
if ($settings['display'] == 'main') {
Blazy::containerAttributes($attributes, $settings);
}
return $attributes;
}
public function preRenderSlick(array $element) {
$build = $element['#build'];
unset($element['#build']);
$settings =& $build['settings'];
$settings += SlickDefault::htmlSettings();
$defaults = Slick::defaultSettings();
if (!empty($settings['thumbnail_effect']) && (!empty($settings['thumbnail_style']) || !empty($settings['thumbnail']))) {
$dots_class[] = 'slick-dots--thumbnail-' . $settings['thumbnail_effect'];
}
if (!empty($settings['skin_dots'])) {
$dots_class[] = 'slick-dots--' . str_replace('_', '-', $settings['skin_dots']);
}
if (isset($dots_class) && !empty($build['optionset'])) {
$dots_class[] = $build['optionset']
->getSetting('dotsClass') ?: 'slick-dots';
$js['dotsClass'] = implode(" ", $dots_class);
}
if ($settings['library'] == 'accessible-slick' && $build['optionset']
->getSetting('autoplay') && $build['optionset']
->getSetting('useAutoplayToggleButton')) {
foreach ([
'pauseIcon',
'playIcon',
] as $setting) {
if ($classes = trim(strip_tags($build['optionset']
->getSetting($setting)))) {
if ($classes != $defaults[$setting]) {
$js[$setting] = '<span class="' . $classes . '" aria-hidden="true"></span>';
}
}
}
}
if (!empty($settings['breaking'])) {
if ($build['optionset']
->getSetting('rows') == 1) {
$js['rows'] = 0;
}
}
if ($settings['display'] == 'main') {
if (!empty($settings['override'])) {
foreach ($settings['overridables'] as $key => $override) {
$js[$key] = empty($override) ? FALSE : TRUE;
}
}
if (!empty($settings['grid']) && !empty($settings['visible_items'])) {
$build['items'] = $this
->buildGrid($build['items'], $settings);
}
}
$build['attributes'] = $this
->prepareAttributes($build);
$build['options'] = isset($js) ? array_merge($build['options'], $js) : $build['options'];
$this->moduleHandler
->alter('slick_optionset', $build['optionset'], $settings);
foreach (SlickDefault::themeProperties() as $key) {
$element["#{$key}"] = $build[$key];
}
unset($build);
return $element;
}
public function buildGrid(array $items = [], array &$settings = []) {
$grids = [];
if (empty($settings['unslick']) && !empty($settings['count'])) {
$settings['unslick'] = $settings['count'] < $settings['visible_items'];
}
if (!empty($settings['unslick'])) {
$settings['display'] = 'main';
$settings['current_item'] = 'grid';
$settings['count'] = 2;
$grids[0] = $this
->buildGridItem($items, 0, $settings);
}
else {
$preserve_keys = !empty($settings['preserve_keys']);
$grid_items = array_chunk($items, $settings['visible_items'], $preserve_keys);
$settings['count'] = count($grid_items);
foreach ($grid_items as $delta => $grid_item) {
$grids[] = $this
->buildGridItem($grid_item, $delta, $settings);
}
}
return $grids;
}
public function buildGridItem(array $items, $delta, array $settings = []) {
$slide = [
'#theme' => 'slick_grid',
'#items' => $items,
'#delta' => $delta,
'#settings' => $settings,
];
return [
'slide' => $slide,
'settings' => $settings,
];
}
public function build(array $build = []) {
foreach (SlickDefault::themeProperties() as $key) {
$build[$key] = isset($build[$key]) ? $build[$key] : [];
}
$slick = [
'#theme' => 'slick_wrapper',
'#items' => [],
'#build' => $build,
'#pre_render' => [
[
$this,
'preRenderSlickWrapper',
],
],
'items' => [],
];
$this->moduleHandler
->alter('slick_build', $slick, $build['settings']);
return empty($build['items']) ? [] : $slick;
}
protected function prepareSettings(array &$element, array &$build) {
$settings = array_merge(SlickDefault::htmlSettings(), $build['settings']);
$id = $settings['id'] = Blazy::getHtmlId('slick', $settings['id']);
$thumb_id = $id . '-thumbnail';
$options = $build['options'];
if (strpos($settings['route_name'], 'layout_builder.') === 0 || !empty($settings['is_preview'])) {
$options['draggable'] = FALSE;
}
if (!empty($settings['skin']) && ($skins = $this->skinManager
->getSkinsByGroup('main'))) {
if (isset($skins[$settings['skin']]['options'])) {
$options = array_merge($options, $skins[$settings['skin']]['options']);
}
}
$build['optionset'] = $build['optionset'] ?: Slick::loadWithFallback($settings['optionset']);
$settings['library'] = $this
->configLoad('library', 'slick.settings');
$settings['breaking'] = $this->skinManager
->isBreaking();
$settings['count'] = empty($settings['count']) ? count($build['items']) : $settings['count'];
$settings['nav'] = $settings['nav'] ?: empty($settings['vanilla']) && !empty($settings['optionset_thumbnail']) && isset($build['items'][1]);
$settings['navpos'] = $settings['nav'] && !empty($settings['thumbnail_position']);
$settings['vertical'] = $build['optionset']
->getSetting('vertical');
$mousewheel = $build['optionset']
->getSetting('mouseWheel');
if ($settings['nav']) {
$options['asNavFor'] = "#{$thumb_id}-slider";
$optionset_thumbnail = $build['optionset_tn'] = Slick::loadWithFallback($settings['optionset_thumbnail']);
$mousewheel = $optionset_thumbnail
->getSetting('mouseWheel');
$settings['vertical_tn'] = $optionset_thumbnail
->getSetting('vertical');
}
else {
if (isset($element['#attributes'])) {
$build['attributes'] = empty($build['attributes']) ? $element['#attributes'] : NestedArray::mergeDeep($build['attributes'], $element['#attributes']);
}
}
if (!empty($settings['check_blazy']) && !empty($settings['first_image'])) {
$this
->isBlazy($settings, $settings['first_image']);
}
if (empty($settings['_lazy'])) {
$build['optionset']
->whichLazy($settings);
}
$settings['mousewheel'] = $mousewheel;
$settings['down_arrow'] = $build['optionset']
->getSetting('downArrow');
$build['options'] = $options;
$build['settings'] = $settings;
$attachments = $this
->attach($settings);
$element['#settings'] = $settings;
$element['#attached'] = empty($build['attached']) ? $attachments : NestedArray::mergeDeep($build['attached'], $attachments);
}
protected function buildNavigation(array &$build, array $thumbs) {
$settings = $build['settings'];
foreach ([
'items',
'options',
'settings',
] as $key) {
$build[$key] = isset($thumbs[$key]) ? $thumbs[$key] : [];
}
$settings = array_merge($settings, $build['settings']);
$settings['optionset'] = $settings['optionset_thumbnail'];
$settings['skin'] = $settings['skin_thumbnail'];
$settings['display'] = 'thumbnail';
$build['optionset'] = $build['optionset_tn'];
$build['settings'] = $settings;
$build['options']['asNavFor'] = "#" . $settings['id'] . '-slider';
unset($build['optionset_tn']);
return $this
->slick($build);
}
public function preRenderSlickWrapper($element) {
$build = $element['#build'];
unset($element['#build']);
$this
->prepareSettings($element, $build);
$thumbs = isset($build['thumb']) ? $build['thumb'] : [];
$settings = $build['settings'];
unset($build['thumb']);
$slick[0] = $this
->slick($build);
if ($settings['nav'] && $thumbs) {
$slick[1] = $this
->buildNavigation($build, $thumbs);
}
if ($settings['navpos']) {
$slick = array_reverse($slick);
}
$element['#items'] = $slick;
$element['#cache'] = $this
->getCacheMetadata($build);
unset($build);
return $element;
}
public function attachSkin(array &$load, $attach = []) {
$this->skinManager
->attachSkin($load, $attach);
}
public function getSkins() {
return $this->skinManager
->getSkins();
}
public function getSkinsByGroup($group = '', $option = FALSE) {
return $this->skinManager
->getSkinsByGroup($group, $option);
}
}