View source
<?php
namespace Drupal\block_visibility_groups;
use Drupal\block\BlockListBuilder;
use Drupal\block_visibility_groups\Entity\BlockVisibilityGroup;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
class BlockVisibilityGroupedListBuilder extends BlockListBuilder {
use BlockVisibilityLister;
use ConditionsSetFormTrait;
const UNSET_GROUP = 'UNSET-GROUP';
const ALL_GROUP = 'ALL-GROUP';
protected $group_storage;
protected $state;
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, ThemeManagerInterface $theme_manager, FormBuilderInterface $form_builder, EntityStorageInterface $block_visibility_group_storage, StateInterface $state, MessengerInterface $messenger) {
parent::__construct($entity_type, $storage, $theme_manager, $form_builder, $messenger);
$this->group_storage = $block_visibility_group_storage;
$this->state = $state;
}
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static($entity_type, $container
->get('entity_type.manager')
->getStorage($entity_type
->id()), $container
->get('theme.manager'), $container
->get('form_builder'), $container
->get('entity_type.manager')
->getStorage('block_visibility_group'), $container
->get('state'), $container
->get('messenger'));
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$group_options = $this
->getBlockVisibilityGroupOptions();
$default_value = $this
->getCurrentBlockVisibilityGroup();
$current_block_visibility_group = NULL;
if (!in_array($default_value, [
BlockVisibilityGroupedListBuilder::ALL_GROUP,
BlockVisibilityGroupedListBuilder::UNSET_GROUP,
])) {
$current_block_visibility_group = $default_value;
}
$options = [];
foreach ($group_options as $key => $group_option) {
if ($default_value == $key) {
$default_value = $group_option['path'];
}
$options[$group_option['path']] = $group_option['label'];
}
$form['block_visibility_group'] = [
'#weight' => -100,
];
$form['block_visibility_group']['select'] = [
'#type' => 'select',
'#title' => $this
->t('Block Visibility Group'),
'#options' => $options,
'#default_value' => $default_value,
'#attributes' => [
'onchange' => 'this.options[this.selectedIndex].value && (window.location = this.options[this.selectedIndex].value)',
],
];
$description = $this
->t('Block Visibility Groups allow you to control the visibility of multiple blocks in one place.');
if (!$this
->groupsExist()) {
$description .= ' ' . $this
->t('No Groups have been created yet.');
$form['block_visibility_group']['create'] = [
'#type' => 'link',
'#title' => t('Create a Group'),
'#url' => Url::fromRoute('entity.block_visibility_group.add_form'),
];
}
else {
if ($current_block_visibility_group) {
$form['block_visibility_group']['block_visibility_group_show_global'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Show Global Blocks'),
'#default_value' => $this
->getShowGlobalWithGroup(),
'#description' => $this
->t('Show global blocks when viewing a visibility group.'),
'#attributes' => [
'onchange' => 'this.form.submit()',
],
];
$group = $this->group_storage
->load($current_block_visibility_group);
$form['block_visibility_group']['help'] = $this
->createHelp($group);
$conditions_element = $this
->createConditionsSet($form, $group, 'layout');
$conditions_element['#type'] = 'details';
if ($this->request->query
->get('show_conditions')) {
$conditions_element['#open'] = TRUE;
}
else {
$conditions_element['#open'] = FALSE;
}
$form['block_visibility_group']['conditions_section'] = $conditions_element;
}
}
$form['block_visibility_group']['select']['#description'] = $description;
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$show_global = $form_state
->getValue('block_visibility_group_show_global', 1);
$this->state
->set('block_visibility_group_show_global', $show_global);
if (!empty($form_state
->getValue('blocks'))) {
parent::submitForm($form, $form_state);
}
}
protected function getCurrentBlockVisibilityGroup() {
$request_id = $this->request->query
->get('block_visibility_group');
if (!$request_id) {
$request_id = BlockVisibilityGroupedListBuilder::ALL_GROUP;
}
return $request_id;
}
protected function getBlockVisibilityGroupOptions() {
$route_options = [
BlockVisibilityGroupedListBuilder::UNSET_GROUP => [
'label' => $this
->t('- Global blocks -'),
],
BlockVisibilityGroupedListBuilder::ALL_GROUP => [
'label' => $this
->t('- All Blocks -'),
],
];
$block_visibility_group_labels = $this
->getBlockVisibilityLabels($this->group_storage);
foreach ($block_visibility_group_labels as $id => $label) {
$route_options[$id] = [
'label' => $label,
];
}
foreach ($route_options as $key => &$route_option) {
$url = Url::fromRoute('block.admin_display_theme', [
'theme' => $this->theme,
], [
'query' => [
'block_visibility_group' => $key,
],
]);
$route_option['path'] = $url
->toString();
}
return $route_options;
}
protected function buildBlocksForm() {
$form = parent::buildBlocksForm();
$show_global_in_group = $this
->getShowGlobalWithGroup();
if ($block_visibility_group = $this
->getBlockVisibilityGroup(TRUE)) {
foreach ($form as &$row_info) {
if (isset($row_info['title']['#url'])) {
$url = $row_info['title']['#url'];
$query = $url
->getOption('query');
$url = Url::fromRoute('block_visibility_groups.admin_library', [
'theme' => $this
->getThemeName(),
'block_visibility_group' => $block_visibility_group,
], [
'query' => $query,
]);
$row_info['title']['#url'] = $url;
}
if (isset($row_info['operations']['#links']) && $row_info['operations']['#links']) {
foreach ($row_info['operations']['#links'] as &$op_info) {
$url = $op_info['url'];
$query = $url
->getOption('query');
$query['block_visibility_group'] = $block_visibility_group;
$url
->setOption('query', $query);
}
}
}
}
if ($this
->getBlockVisibilityGroup() == static::ALL_GROUP || $block_visibility_group && $show_global_in_group) {
$this
->addGroupColumn($form);
}
return $form;
}
protected function getBlockVisibilityGroup($groups_only = FALSE) {
$group = $this->request->query
->get('block_visibility_group');
if ($groups_only && in_array($group, [
$this::ALL_GROUP,
$this::UNSET_GROUP,
])) {
return NULL;
}
return $group;
}
protected function getEntityIds() {
$entity_ids = parent::getEntityIds();
$current_block_visibility_group = $this
->getCurrentBlockVisibilityGroup();
$show_global_in_group = $this
->getShowGlobalWithGroup();
if (!empty($current_block_visibility_group) && $current_block_visibility_group != $this::ALL_GROUP) {
$entities = $this->storage
->loadMultipleOverrideFree($entity_ids);
foreach ($entities as $block) {
$config_block_visibility_group = $this
->getGroupForBlock($block);
if (static::UNSET_GROUP == $current_block_visibility_group) {
if (!empty($config_block_visibility_group)) {
unset($entity_ids[$block
->id()]);
}
}
elseif ($config_block_visibility_group != $current_block_visibility_group && !(empty($config_block_visibility_group) && $show_global_in_group)) {
unset($entity_ids[$block
->id()]);
}
}
}
return $entity_ids;
}
protected function groupsExist() {
return !empty($this->group_storage
->loadMultiple());
}
protected function addGroupColumn(array &$form) {
$entity_ids = [];
foreach (array_keys($form) as $row_key) {
if (strpos($row_key, 'region-') !== 0) {
$entity_ids[] = $row_key;
}
}
$entities = $this->storage
->loadMultipleOverrideFree($entity_ids);
if (!empty($entities)) {
$labels = $this
->getBlockVisibilityLabels($this->group_storage);
foreach ($entities as $block) {
if (!empty($form[$block
->id()])) {
$visibility_group = $this
->t('Global');
$conditions = $block
->getVisibilityConditions();
if ($conditions
->has('condition_group')) {
$condition_config = $conditions
->get('condition_group')
->getConfiguration();
if (isset($labels[$condition_config['block_visibility_group']])) {
$visibility_group = '<strong>' . $labels[$condition_config['block_visibility_group']] . '</strong>';
}
}
$row =& $form[$block
->id()];
foreach (Element::children($row) as $i => $child) {
$row[$child]['#weight'] = $i;
}
$row['block_visibility_group'] = [
'#markup' => $visibility_group,
'#weight' => 1.5,
];
$row['#sorted'] = FALSE;
}
}
array_splice($form['#header'], 2, 0, [
$this
->t('Visibility group'),
]);
foreach (Element::children($form) as $child) {
foreach (Element::children($form[$child]) as $gchild) {
if (isset($form[$child][$gchild]['#wrapper_attributes']['colspan'])) {
$form[$child][$gchild]['#wrapper_attributes']['colspan'] = $form[$child][$gchild]['#wrapper_attributes']['colspan'] + 1;
}
}
}
}
}
protected function getShowGlobalWithGroup() {
return $this->state
->get('block_visibility_group_show_global', 1);
}
protected function createHelp(BlockVisibilityGroup $group) {
$help = '<strong>' . $this
->t('Currently viewing') . ': <em>' . $group
->label() . '</em></strong>';
if ($group
->getLogic() == 'and') {
$help .= '<p>' . $this
->t('All conditions must pass.') . '</p>';
}
else {
$help .= '<p>' . $this
->t('Only one condition must pass.') . '</p>';
}
if ($group
->isAllowOtherConditions()) {
$help .= '<p>' . $this
->t('Blocks in this group may have other conditions.') . '</p>';
}
else {
$help .= '<p>' . $this
->t('Blocks in this group may <strong>not</strong> have other conditions.') . '</p>';
}
$help_group = [
'#type' => 'details',
'#open' => FALSE,
'#title' => $this
->t('Group Settings'),
'text' => [
'#type' => 'markup',
'#markup' => $help,
],
'edit' => [
'#type' => 'link',
'#title' => t('Edit Group Settings'),
'#url' => $group
->toUrl('edit-form'),
],
];
return $help_group;
}
}