View source
<?php
namespace Drupal\block;
use Drupal\Component\Utility\Html;
use Drupal\Core\Plugin\PluginFormFactoryInterface;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Executable\ExecutableManagerInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\Plugin\PluginWithFormsInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class BlockForm extends EntityForm {
protected $entity;
protected $storage;
protected $manager;
protected $language;
protected $themeHandler;
protected $contextRepository;
protected $pluginFormFactory;
protected $blockRepository;
public function __construct(EntityTypeManagerInterface $entity_type_manager, ExecutableManagerInterface $manager, ContextRepositoryInterface $context_repository, LanguageManagerInterface $language, ThemeHandlerInterface $theme_handler, PluginFormFactoryInterface $plugin_form_manager, ?BlockRepositoryInterface $block_repository = NULL) {
if ($block_repository === NULL) {
@trigger_error('Calling ' . __METHOD__ . ' without the $block_repository argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3333575', E_USER_DEPRECATED);
$block_repository = \Drupal::service('block.repository');
}
$this->storage = $entity_type_manager
->getStorage('block');
$this->manager = $manager;
$this->contextRepository = $context_repository;
$this->language = $language;
$this->themeHandler = $theme_handler;
$this->pluginFormFactory = $plugin_form_manager;
$this->blockRepository = $block_repository;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('plugin.manager.condition'), $container
->get('context.repository'), $container
->get('language_manager'), $container
->get('theme_handler'), $container
->get('plugin_form.factory'), $container
->get('block.repository'));
}
public function form(array $form, FormStateInterface $form_state) {
$entity = $this->entity;
$form_state
->setTemporaryValue('gathered_contexts', $this->contextRepository
->getAvailableContexts());
$form['#tree'] = TRUE;
$form['settings'] = [];
$subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
$form['settings'] = $this
->getPluginForm($entity
->getPlugin())
->buildConfigurationForm($form['settings'], $subform_state);
$form['visibility'] = $this
->buildVisibilityInterface([], $form_state);
$form['id'] = [
'#type' => 'machine_name',
'#maxlength' => 64,
'#description' => $this
->t('A unique name for this block instance. Must be alpha-numeric and underscore separated.'),
'#default_value' => !$entity
->isNew() ? $entity
->id() : $this
->getUniqueMachineName($entity),
'#machine_name' => [
'exists' => '\\Drupal\\block\\Entity\\Block::load',
'replace_pattern' => '[^a-z0-9_.]+',
'source' => [
'settings',
'label',
],
],
'#required' => TRUE,
'#disabled' => !$entity
->isNew(),
];
if ($theme = $entity
->getTheme()) {
$form['theme'] = [
'#type' => 'value',
'#value' => $theme,
];
}
else {
$theme = $this
->config('system.theme')
->get('default');
$theme_options = [];
foreach ($this->themeHandler
->listInfo() as $theme_name => $theme_info) {
if (!empty($theme_info->status)) {
$theme_options[$theme_name] = $theme_info->info['name'];
}
}
$form['theme'] = [
'#type' => 'select',
'#options' => $theme_options,
'#title' => $this
->t('Theme'),
'#default_value' => $theme,
'#ajax' => [
'callback' => '::themeSwitch',
'wrapper' => 'edit-block-region-wrapper',
],
];
}
$weight = $entity
->isNew() ? $this
->getRequest()->query
->get('weight', 0) : $entity
->getWeight();
$form['weight'] = [
'#type' => 'hidden',
'#default_value' => $weight,
];
$entity_region = $entity
->getRegion();
$region = $entity
->isNew() ? $this
->getRequest()->query
->get('region', $entity_region) : $entity_region;
$form['region'] = [
'#type' => 'select',
'#title' => $this
->t('Region'),
'#description' => $this
->t('Select the region where this block should be displayed.'),
'#default_value' => $region,
'#required' => TRUE,
'#options' => system_region_list($form_state
->getValue('theme', $theme), REGIONS_VISIBLE),
'#prefix' => '<div id="edit-block-region-wrapper">',
'#suffix' => '</div>',
];
$form['#attached']['library'][] = 'block/drupal.block.admin';
return $form;
}
public function themeSwitch($form, FormStateInterface $form_state) {
return $form['region'];
}
protected function buildVisibilityInterface(array $form, FormStateInterface $form_state) {
$form['visibility_tabs'] = [
'#type' => 'vertical_tabs',
'#title' => $this
->t('Visibility'),
'#parents' => [
'visibility_tabs',
],
'#attached' => [
'library' => [
'block/drupal.block',
],
],
];
$visibility = $this->entity
->getVisibility();
$definitions = $this->manager
->getFilteredDefinitions('block_ui', $form_state
->getTemporaryValue('gathered_contexts'), [
'block' => $this->entity,
]);
foreach ($definitions as $condition_id => $definition) {
if ($condition_id == 'current_theme') {
continue;
}
if ($condition_id == 'language' && !$this->language
->isMultilingual()) {
continue;
}
$condition = $this->manager
->createInstance($condition_id, $visibility[$condition_id] ?? []);
$form_state
->set([
'conditions',
$condition_id,
], $condition);
$condition_form = $condition
->buildConfigurationForm([], $form_state);
$condition_form['#type'] = 'details';
$condition_form['#title'] = $condition
->getPluginDefinition()['label'];
$condition_form['#group'] = 'visibility_tabs';
$form[$condition_id] = $condition_form;
}
$disable_negation = [
'entity_bundle:node',
'language',
'response_status',
'user_role',
];
foreach ($disable_negation as $condition) {
if (isset($form[$condition])) {
$form[$condition]['negate']['#type'] = 'value';
$form[$condition]['negate']['#value'] = $form[$condition]['negate']['#default_value'];
}
}
if (isset($form['user_role'])) {
$form['user_role']['#title'] = $this
->t('Roles');
unset($form['user_role']['roles']['#description']);
}
if (isset($form['request_path'])) {
$form['request_path']['#title'] = $this
->t('Pages');
$form['request_path']['negate']['#type'] = 'radios';
$form['request_path']['negate']['#default_value'] = (int) $form['request_path']['negate']['#default_value'];
$form['request_path']['negate']['#title_display'] = 'invisible';
$form['request_path']['negate']['#options'] = [
$this
->t('Show for the listed pages'),
$this
->t('Hide for the listed pages'),
];
}
return $form;
}
protected function actions(array $form, FormStateInterface $form_state) {
$actions = parent::actions($form, $form_state);
$actions['submit']['#value'] = $this
->t('Save block');
$actions['delete']['#title'] = $this
->t('Remove block');
return $actions;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$form_state
->setValue('weight', (int) $form_state
->getValue('weight'));
$this
->getPluginForm($this->entity
->getPlugin())
->validateConfigurationForm($form['settings'], SubformState::createForSubform($form['settings'], $form, $form_state));
$this
->validateVisibility($form, $form_state);
}
protected function validateVisibility(array $form, FormStateInterface $form_state) {
foreach ($form_state
->getValue('visibility') as $condition_id => $values) {
$condition = $form_state
->get([
'conditions',
$condition_id,
]);
$condition
->validateConfigurationForm($form['visibility'][$condition_id], SubformState::createForSubform($form['visibility'][$condition_id], $form, $form_state));
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$entity = $this->entity;
$sub_form_state = SubformState::createForSubform($form['settings'], $form, $form_state);
$block = $entity
->getPlugin();
$this
->getPluginForm($block)
->submitConfigurationForm($form, $sub_form_state);
if ($block instanceof ContextAwarePluginInterface && $block
->getContextDefinitions()) {
$context_mapping = $sub_form_state
->getValue('context_mapping', []);
$block
->setContextMapping($context_mapping);
}
$this
->submitVisibility($form, $form_state);
}
public function save(array $form, FormStateInterface $form_state) {
$value = parent::save($form, $form_state);
$this
->messenger()
->addStatus($this
->t('The block configuration has been saved.'));
$form_state
->setRedirect('block.admin_display_theme', [
'theme' => $form_state
->getValue('theme'),
], [
'query' => [
'block-placement' => Html::getClass($this->entity
->id()),
],
]);
return $value;
}
protected function submitVisibility(array $form, FormStateInterface $form_state) {
foreach ($form_state
->getValue('visibility') as $condition_id => $values) {
$condition = $form_state
->get([
'conditions',
$condition_id,
]);
$condition
->submitConfigurationForm($form['visibility'][$condition_id], SubformState::createForSubform($form['visibility'][$condition_id], $form, $form_state));
$condition_configuration = $condition
->getConfiguration();
$this->entity
->getVisibilityConditions()
->addInstanceId($condition_id, $condition_configuration);
}
}
public function getUniqueMachineName(BlockInterface $block) {
$suggestion = $block
->getPlugin()
->getMachineNameSuggestion();
return $this->blockRepository
->getUniqueMachineName($suggestion, $block
->getTheme());
}
protected function getPluginForm(BlockPluginInterface $block) {
if ($block instanceof PluginWithFormsInterface) {
return $this->pluginFormFactory
->createInstance($block, 'configure');
}
return $block;
}
}