View source
<?php
namespace Drupal\context\Reaction\Blocks\Form;
use Drupal\context\ContextManager;
use Drupal\context\ContextReactionManager;
use Drupal\context\Form\AjaxFormTrait;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\RemoveCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormState;
use Drupal\context\ContextInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
use Drupal\Core\Render\Element\StatusMessages;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
abstract class BlockFormBase extends FormBase {
use AjaxFormTrait;
protected $block;
protected $context;
protected $reaction;
protected $blockManager;
protected $contextRepository;
protected $themeHandler;
protected $formBuilder;
protected $contextReactionManager;
protected $contextManager;
protected $request;
public function __construct(PluginManagerInterface $block_manager, ContextRepositoryInterface $contextRepository, ThemeHandlerInterface $themeHandler, FormBuilderInterface $formBuilder, ContextReactionManager $contextReactionManager, ContextManager $contextManager, RequestStack $requestStack) {
$this->blockManager = $block_manager;
$this->contextRepository = $contextRepository;
$this->themeHandler = $themeHandler;
$this->formBuilder = $formBuilder;
$this->contextReactionManager = $contextReactionManager;
$this->contextManager = $contextManager;
$this->request = $requestStack
->getCurrentRequest();
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.block'), $container
->get('context.repository'), $container
->get('theme_handler'), $container
->get('form_builder'), $container
->get('plugin.manager.context_reaction'), $container
->get('context.manager'), $container
->get('request_stack'));
}
protected abstract function prepareBlock($block_id);
protected abstract function getSubmitValue();
public function buildForm(array $form, FormStateInterface $form_state, ContextInterface $context = NULL, $reaction_id = NULL, $block_id = NULL) {
$this->context = $context;
$this->reaction = $this->context
->getReaction($reaction_id);
$this->block = $this
->prepareBlock($block_id);
$theme = $this
->getRequest()->query
->get('theme', $this->themeHandler
->getDefault());
$form_state
->set('block_theme', $theme);
$form_state
->setTemporaryValue('gathered_contexts', $this->contextRepository
->getAvailableContexts());
$configuration = $this->block
->getConfiguration();
$form['#tree'] = TRUE;
$form['settings'] = $this->block
->buildConfigurationForm([], $form_state);
$form['settings']['id'] = [
'#type' => 'value',
'#value' => $this->block
->getPluginId(),
];
$form['custom_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' => isset($configuration['custom_id']) ? $configuration['custom_id'] : preg_replace("/\\W+/", "_", $this->block
->getPluginId()),
'#machine_name' => [
'source' => [
'settings',
'label',
],
],
'#required' => TRUE,
];
$form['region'] = [
'#type' => 'select',
'#title' => $this
->t('Region'),
'#description' => $this
->t('Select the region where this block should be displayed.'),
'#options' => $this
->getThemeRegionOptions($theme),
'#default_value' => isset($configuration['region']) ? $configuration['region'] : '',
];
$form['unique'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Unique'),
'#description' => $this
->t('Check if the block should be uniquely placed, this means that the block can not be overridden by other blocks of the same type in the selected region.'),
'#default_value' => isset($configuration['unique']) ? $configuration['unique'] : FALSE,
];
$form['theme'] = [
'#type' => 'value',
'#value' => $theme,
];
$form['css_class'] = [
'#type' => 'textfield',
'#title' => $this
->t('Block Class'),
'#default_value' => isset($configuration['css_class']) ? $configuration['css_class'] : '',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this
->getSubmitValue(),
'#button_type' => 'primary',
'#ajax' => [
'callback' => '::submitFormAjax',
],
];
if (!$this->request
->isXmlHttpRequest()) {
unset($form['actions']['submit']['#ajax']);
}
$form_state
->disableCache();
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$settings = (new FormState())
->setValues($form_state
->getValue('settings'));
$this->block
->submitConfigurationForm($form, $settings);
$form_state
->setValue('settings', $settings
->getValues());
if ($this->block instanceof ContextAwarePluginInterface) {
$this->block
->setContextMapping($form_state
->getValue([
'settings',
'context_mapping',
], []));
}
$configuration = array_merge($this->block
->getConfiguration(), [
'custom_id' => $form_state
->getValue('custom_id'),
'region' => $form_state
->getValue('region'),
'theme' => $form_state
->getValue('theme'),
'css_class' => $form_state
->getValue('css_class'),
'unique' => $form_state
->getValue('unique'),
'context_id' => $this->context
->id(),
]);
if (!isset($configuration['uuid'])) {
$this->reaction
->addBlock($configuration);
}
else {
$this->reaction
->updateBlock($configuration['uuid'], $configuration);
}
$this->context
->save();
$form_state
->setRedirectUrl(Url::fromRoute('entity.context.edit_form', [
'context' => $this->context
->id(),
]));
}
public function submitFormAjax(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
if ($form_state
->getErrors()) {
$messages = StatusMessages::renderMessages(NULL);
$output[] = $messages;
$output[] = $form;
$form_class = '.' . str_replace('_', '-', $form_state
->getFormObject()
->getFormId());
$response
->addCommand(new RemoveCommand('#drupal-modal .messages--error'));
$response
->addCommand(new ReplaceCommand($form_class, $output));
}
else {
$form = $this->contextManager
->getForm($this->context, 'edit');
$response
->addCommand(new CloseModalDialogCommand());
$response
->addCommand(new ReplaceCommand('#context-reactions', $form['reactions']));
}
return $response;
}
protected function getThemeRegionOptions($theme, $show = REGIONS_ALL) {
$regions = system_region_list($theme, $show);
foreach ($regions as $region => $title) {
$regions[$region] = $title;
}
return $regions;
}
}