View source
<?php
namespace Drupal\layout_builder_restrictions_by_region\Form;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Renderer;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\Core\Url;
use Drupal\layout_builder_restrictions\Traits\PluginHelperTrait;
use Drupal\layout_builder_restrictions_by_region\Traits\LayoutBuilderRestrictionsByRegionHelperTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class AllowedBlocksForm extends FormBase {
use PluginHelperTrait;
use LayoutBuilderRestrictionsByRegionHelperTrait;
protected $requestStack;
protected $layoutManager;
protected $entityTypeManager;
protected $privateTempStoreFactory;
protected $messenger;
protected $renderer;
protected $allowedBlockCategories;
protected $tempData;
protected $whitelistedBlocks;
protected $blacklistedBlocks;
protected $restrictedCategories;
protected $layoutPluginId;
protected $regionId;
protected $staticId;
public function __construct(RequestStack $request_stack, LayoutPluginManagerInterface $layout_manager, EntityTypeManager $entity_type_manager, PrivateTempStoreFactory $private_temp_store_factory, MessengerInterface $messenger, Renderer $renderer) {
$this->requestStack = $request_stack;
$this->layoutManager = $layout_manager;
$this->entityTypeManager = $entity_type_manager;
$this->privateTempStoreFactory = $private_temp_store_factory;
$this->messenger = $messenger;
$this->renderer = $renderer;
$current_request = $this->requestStack
->getCurrentRequest();
$entity_view_display_id = $current_request->query
->get('entity_view_display_id');
$display = $this->entityTypeManager
->getStorage('entity_view_display')
->load($entity_view_display_id);
$this->layoutPluginId = $current_request->query
->get('layout_plugin');
$this->regionId = $current_request->query
->get('region_id');
$this->allowedBlockCategories = $display
->getThirdPartySetting('layout_builder_restrictions', 'allowed_block_categories', []);
$third_party_settings = $display
->getThirdPartySetting('layout_builder_restrictions', 'entity_view_mode_restriction_by_region', []);
$this->whitelistedBlocks = isset($third_party_settings['whitelisted_blocks'][$this->layoutPluginId][$this->regionId]) ? $third_party_settings['whitelisted_blocks'][$this->layoutPluginId][$this->regionId] : [];
$this->blacklistedBlocks = isset($third_party_settings['blacklisted_blocks'][$this->layoutPluginId][$this->regionId]) ? $third_party_settings['blacklisted_blocks'][$this->layoutPluginId][$this->regionId] : [];
$this->restrictedCategories = isset($third_party_settings['restricted_categories'][$this->layoutPluginId][$this->regionId]) ? $third_party_settings['restricted_categories'][$this->layoutPluginId][$this->regionId] : [];
}
public static function create(ContainerInterface $container) {
return new static($container
->get('request_stack'), $container
->get('plugin.manager.core.layout'), $container
->get('entity_type.manager'), $container
->get('tempstore.private'), $container
->get('messenger'), $container
->get('renderer'));
}
public function getFormId() {
return 'layout_builder_by_region_allowed_blocks';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$current_request = $this->requestStack
->getCurrentRequest();
$static_id = $current_request->query
->get('static_id');
$entity_view_display_id = $current_request->query
->get('entity_view_display_id');
$layout_plugin = $current_request->query
->get('layout_plugin');
$region_id = $current_request->query
->get('region_id');
$display = $this->entityTypeManager
->getStorage('entity_view_display')
->load($entity_view_display_id);
$tempstore = $this->privateTempStoreFactory;
$store = $tempstore
->get('layout_builder_restrictions_by_region');
$temp_data = $store
->get($static_id . ':' . $layout_plugin . ':' . $region_id);
$layout_definition = $this->layoutManager
->getDefinition($layout_plugin);
$regions = $layout_definition
->getRegions();
$regions['all_regions'] = [
'label' => $this
->t('All regions'),
];
$region_label = $regions[$region_id]['label']
->render();
$layout_label = $layout_definition
->getLabel();
$form['config_context_markup'] = [
'#markup' => $this
->t('<strong>Layout:</strong> @layout_label<br><strong>Region:</strong> @region_label', [
'@layout_label' => $layout_label,
'@region_label' => $region_label,
]),
];
foreach ($this
->getBlockDefinitions($display) as $category => $data) {
$title = $data['label'];
if (!empty($data['translated_label'])) {
$title = $data['translated_label'];
}
$category_form = [
'#type' => 'fieldset',
'#title' => $title,
];
$category_form['restriction_behavior'] = [
'#type' => 'radios',
'#options' => [
"all" => $this
->t('Allow all existing & new %category blocks.', [
'%category' => $data['label'],
]),
"restrict_all" => $this
->t('Restrict all existing & new %category blocks.', [
'%category' => $data['label'],
]),
"whitelisted" => $this
->t('Allow specific %category blocks:', [
'%category' => $data['label'],
]),
"blacklisted" => $this
->t('Restrict specific %category blocks:', [
'%category' => $data['label'],
]),
],
'#parents' => [
'allowed_blocks',
$category,
'restriction',
],
];
$category_form['restriction_behavior']['#default_value'] = $this
->getCategoryBehavior($category, $temp_data);
$category_form['allowed_blocks'] = [
'#type' => 'container',
'#states' => [
'invisible' => [
[
':input[name="allowed_blocks[' . $category . '][restriction]"]' => [
'value' => "all",
],
],
[
':input[name="allowed_blocks[' . $category . '][restriction]"]' => [
'value' => "restrict_all",
],
],
],
],
];
foreach ($data['definitions'] as $block_id => $block) {
$category_form['allowed_blocks'][$block_id] = [
'#type' => 'checkbox',
'#title' => $block['admin_label'],
'#default_value' => $this
->getBlockDefault($block_id, $category, $temp_data),
'#parents' => [
'allowed_blocks',
$category,
'allowed_blocks',
$block_id,
],
];
}
if ($category == 'Custom blocks' || $category == 'Custom block types') {
$category_form['description'] = [
'#type' => 'container',
'#children' => $this
->t('<p>In the event both <em>Custom Block Types</em> and <em>Custom Blocks</em> restrictions are enabled, <em>Custom Block Types</em> restrictions are disregarded.</p>'),
'#states' => [
'visible' => [
':input[name="allowed_blocks[' . $category . '][restriction]"]' => [
'value' => "restricted",
],
],
],
];
}
$form['allowed_blocks'][$category] = $category_form;
}
$form['static_id'] = [
'#type' => 'hidden',
'#value' => $static_id,
];
$form['layout_plugin'] = [
'#type' => 'hidden',
'#value' => $layout_plugin,
];
$form['region_id'] = [
'#type' => 'hidden',
'#value' => $region_id,
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this
->t('Save'),
'#ajax' => [
'callback' => '::ajaxSubmit',
'event' => 'click',
'url' => Url::fromRoute("layout_builder_restrictions_by_region.{$display->getTargetEntityTypeId()}_allowed_blocks", [
'static_id' => $static_id,
'entity_view_display_id' => $entity_view_display_id,
'layout_plugin' => $layout_plugin,
'region_id' => $region_id,
]),
'options' => [
'query' => [
FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
],
],
],
];
return $form;
}
public function ajaxSubmit(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
$static_id = $values['static_id'];
$layout_plugin = $values['layout_plugin'];
$region_id = $values['region_id'];
$categories = $values['allowed_blocks'];
$block_restrictions = [];
if (!empty($categories)) {
foreach ($categories as $category => $category_setting) {
$restriction_type = $category_setting['restriction'];
$block_restrictions[$category]['restriction_type'] = $restriction_type;
if (in_array($restriction_type, [
'whitelisted',
'blacklisted',
])) {
foreach ($category_setting['allowed_blocks'] as $block_id => $block_setting) {
if ($block_setting == '1') {
$block_restrictions[$category]['restrictions'][$block_id] = $block_setting;
}
}
}
}
}
$tempstore = $this->privateTempStoreFactory;
$store = $tempstore
->get('layout_builder_restrictions_by_region');
$store
->set($static_id . ':' . $layout_plugin . ':' . $region_id, $block_restrictions);
$response = new AjaxResponse();
if ($form_state
->getErrors()) {
}
else {
$command = new CloseModalDialogCommand();
$response
->addCommand($command);
$this->messenger
->addWarning($this
->t('There is unsaved Layout Builder Restrictions configuration.'));
$status_messages = [
'#type' => 'status_messages',
];
$messages = $this->renderer
->renderRoot($status_messages);
$messages = '<div id="layout-builder-restrictions-messages">' . $messages . '</div>';
if (!empty($messages)) {
$response
->addCommand(new ReplaceCommand('#layout-builder-restrictions-messages', $messages));
}
$region_status = $this
->RegionRestrictionStatusString($layout_plugin, $region_id, $static_id, NULL);
$response
->addCommand(new ReplaceCommand('#restriction-status--' . $layout_plugin . '--' . $region_id . ' .data', '<span class="data">' . $region_status . '</span>'));
}
return $response;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
}
public function submitForm(array &$form, FormStateInterface $form_state) {
}
protected function getCategoryBehavior($category, $temp_data) {
$category_is_restricted = !empty($this->allowedBlockCategories) && !in_array($category, $this->allowedBlockCategories);
if (!is_null($temp_data[$category]['restriction_type'])) {
return $temp_data[$category]['restriction_type'];
}
else {
if (isset($this->whitelistedBlocks) && in_array($category, array_keys($this->whitelistedBlocks))) {
return "whitelisted";
}
elseif (isset($this->blacklistedBlocks) && in_array($category, array_keys($this->blacklistedBlocks))) {
return "blacklisted";
}
elseif (in_array($category, $this->restrictedCategories)) {
return 'restrict_all';
}
elseif ($category_is_restricted) {
return "restrict_all";
}
else {
return 'all';
}
}
}
protected function getBlockDefault($block_id, $category, $temp_data) {
if (!is_null($temp_data)) {
if (isset($temp_data[$category]['restrictions'])) {
return in_array($block_id, array_keys($temp_data[$category]['restrictions']));
}
else {
return FALSE;
}
}
else {
if (isset($this->whitelistedBlocks[$category])) {
return in_array($block_id, $this->whitelistedBlocks[$category]);
}
if (isset($this->blacklistedBlocks[$category])) {
return in_array($block_id, $this->blacklistedBlocks[$category]);
}
else {
return FALSE;
}
}
return FALSE;
}
}