View source
<?php
namespace Drupal\slick_views\Plugin\views\style;
use Drupal\Core\Form\FormStateInterface;
use Drupal\blazy\Blazy;
class SlickGrouping extends SlickViewsBase {
protected $usesGrouping = TRUE;
protected $usesFields = TRUE;
protected function defineOptions() {
$options = parent::defineOptions();
foreach ([
'limit',
'optionset',
] as $key) {
$options['grouping_' . $key] = [
'default' => '',
];
}
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$definition = $this
->getDefinedFormScopes();
$states = [
'visible' => [
'select[name*="[grouping][0][field]"]' => [
'!value' => '',
],
],
];
if (!isset($form['grouping_limit'])) {
$form['grouping_limit'] = [
'#type' => 'textfield',
'#title' => $this
->t('Grouping limit'),
'#default_value' => $this->options['grouping_limit'],
'#description' => $this
->t('Limit the amount of rows per group. Leave it empty, or 0, for no limit. Applicable only to the first level. Be sure having enough rows.'),
'#enforced' => TRUE,
'#states' => $states,
];
}
if (!isset($form['grouping_optionset'])) {
$form['grouping_optionset'] = [
'#type' => 'select',
'#title' => $this
->t('Grouping optionset'),
'#options' => $this
->admin()
->getOptionsetsByGroupOptions('main'),
'#default_value' => $this->options['grouping_optionset'],
'#description' => $this
->t('If provided, the grouping header will be treated as Slick tabs and acts like simple filters. Else regular stacking slicks. Requires: Optionset thumbnail, Vanilla unchecked, and Randomize option disabled for all optionsets, else impressing broken grouping due to reordered slides. Combine with grids to have a complete insanity.'),
'#enforced' => TRUE,
'#states' => $states,
];
}
$groupings = $this->options['grouping'] ?: [];
for ($i = 0; $i <= count($groupings); $i++) {
foreach ([
'rendered',
'rendered_strip',
] as $key) {
$form['grouping'][$i][$key]['#field_suffix'] = ' ';
$form['grouping'][$i][$key]['#title_display'] = 'before';
}
}
$this
->buildSettingsForm($form, $definition);
if (isset($form['optionset_thumbnail'])) {
$form['optionset_thumbnail']['#description'] .= ' ' . $this
->t('This will be used (taken over) for grouping tabs if Grouping optionset is provided. Including all thumbnail-related options: Skin tthumbnail, Thumbnail position.');
}
}
public function render() {
$sets = parent::render();
$settings = $this->options;
$grouping = empty($settings['grouping']) ? [] : array_filter($settings['grouping']);
$tabs = !empty($settings['grouping_optionset']) && !empty($settings['optionset_thumbnail']);
$tags = [
'span',
'a',
'em',
'strong',
'i',
'button',
];
if (!empty($grouping) && $tabs) {
foreach ($sets as $set) {
$options = [];
$options['nav'] = TRUE;
$options['skin'] = '';
$options['skin_thumbnail'] = $settings['skin_thumbnail'];
$options['thumbnail_position'] = $settings['thumbnail_position'];
$options['optionset'] = $settings['grouping_optionset'];
$options['optionset_thumbnail'] = $settings['optionset_thumbnail'];
$slide = [
'settings' => $options,
'slide' => $set,
];
$thumb['slide']['#markup'] = empty($set['#title']) ? '' : strip_tags($set['#title'], '<span><a><em><strong><i><button>');
$thumb['slide']['#allowed_tags'] = $tags;
$build['items'][] = $slide;
$build['thumb']['items'][] = $thumb;
unset($slide, $thumb);
}
$build['settings'] = $options;
$sets = $this->manager
->build($build);
}
return $sets;
}
protected function renderRowGroup(array $rows = [], $level = 0) {
$view = $this->view;
$settings = $this->options;
$view_name = $view->storage
->id();
$view_mode = $view->current_display;
$plugin_id = $this
->getPluginId();
$grouping = empty($settings['grouping']) ? [] : array_filter($settings['grouping']);
$id = $grouping ? "{$view_name}-{$view_mode}-{$level}" : "{$view_name}-{$view_mode}";
$id = Blazy::getHtmlId($plugin_id . '-views-' . $id, $settings['id']);
$settings = $this
->buildSettings();
$settings['id'] = $id;
if (empty($grouping) && empty($settings['grouping_optionset'])) {
$settings['nav'] = !$settings['vanilla'] && $settings['optionset_thumbnail'] && isset($view->result[1]);
}
$build = $this
->buildElements($settings, $rows);
if (empty($settings['vanilla']) && isset($build['items'][0])) {
$this
->blazyManager()
->isBlazy($settings, $build['items'][0]);
}
$settings['first_image'] = isset($rows[0]) ? $this
->getFirstImage($rows[0]) : [];
$build['settings'] = $settings;
return $this->manager
->build($build);
}
public function renderGroupingSets($sets) {
$output = [];
$grouping = empty($this->options['grouping']) ? [] : array_filter($this->options['grouping']);
foreach ($sets as $set) {
$level = isset($set['level']) ? $set['level'] : 0;
$row = reset($set['rows']);
if (is_array($row) && isset($row['group'])) {
$single_output = [
'#theme' => $this->view
->buildThemeFunctions($this->groupingTheme),
'#view' => $this->view,
'#grouping' => $grouping[$level],
'#rows' => $set['rows'],
];
}
else {
$slick = $this
->renderRowGroup($set['rows'], $level);
if (!empty($grouping) && $level == 0) {
if (empty($this->options['grouping_optionset'])) {
$content[0] = $slick;
$content[0]['#prefix'] = '<h2 class="view-grouping-header">' . $set['group'] . '</h2>';
$single_output = $content;
$single_output['#theme_wrappers'][] = 'container';
$single_output['#attributes']['class'][] = 'view-grouping';
}
else {
$single_output = $slick;
}
}
else {
$single_output = $slick;
}
}
$single_output['#grouping_level'] = $level;
$single_output['#title'] = $set['group'];
$output[] = $single_output;
}
return $output;
}
public function renderGrouping($records, $groupings = [], $group_rendered = NULL) {
$sets = parent::renderGrouping($records, $groupings, $group_rendered);
$grouping = empty($groupings) ? [] : array_filter($groupings);
if (!empty($grouping) && !empty($this->options['grouping_limit'])) {
$new_sets = array_values($sets);
$sets = [];
foreach ($new_sets as $set) {
$set['rows'] = array_slice($set['rows'], 0, $this->options['grouping_limit'], TRUE);
$sets[] = $set;
}
}
return $sets;
}
}