You are here

abstract class BlockFormBase in Context 8

Same name and namespace in other branches
  1. 8.4 src/Reaction/Blocks/Form/BlockFormBase.php \Drupal\context\Reaction\Blocks\Form\BlockFormBase
  2. 8.0 src/Reaction/Blocks/Form/BlockFormBase.php \Drupal\context\Reaction\Blocks\Form\BlockFormBase

Hierarchy

Expanded class hierarchy of BlockFormBase

File

src/Reaction/Blocks/Form/BlockFormBase.php, line 27

Namespace

Drupal\context\Reaction\Blocks\Form
View source
abstract class BlockFormBase extends FormBase {
  use AjaxFormTrait;

  /**
   * The plugin being configured.
   *
   * @var \Drupal\Core\Block\BlockPluginInterface
   */
  protected $block;

  /**
   * The context entity the reaction belongs to.
   *
   * @var ContextInterface
   */
  protected $context;

  /**
   * The blocks reaction this block should be added to.
   *
   * @var \Drupal\context\Plugin\ContextReaction\Blocks
   */
  protected $reaction;

  /**
   * The block manager.
   *
   * @var \Drupal\Component\Plugin\PluginManagerInterface
   */
  protected $blockManager;

  /**
   * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
   */
  protected $contextRepository;

  /**
   * @var \Drupal\Core\Extension\ThemeHandlerInterface
   */
  protected $themeHandler;

  /**
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
  protected $formBuilder;

  /**
   * @var \Drupal\context\ContextReactionManager
   */
  protected $contextReactionManager;

  /**
   * @var \Drupal\context\ContextManager
   */
  protected $contextManager;

  /**
   * @var \Symfony\Component\HttpFoundation\Request
   */
  protected $request;

  /**
   * Constructs a new VariantPluginFormBase.
   *
   * @param \Drupal\Component\Plugin\PluginManagerInterface $block_manager
   *   The block manager.
   *
   * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $contextRepository
   *
   * @param \Drupal\Core\Extension\ThemeHandlerInterface $themeHandler
   * @param \Drupal\Core\Form\FormBuilderInterface $formBuilder
   * @param \Drupal\context\ContextReactionManager $contextReactionManager
   * @param \Drupal\context\ContextManager $contextManager
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
   */
  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();
  }

  /**
   * {@inheritdoc}
   */
  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'));
  }

  /**
   * Prepares the block plugin based on the block ID.
   *
   * @param string $block_id
   *   Either a block ID, or the plugin ID used to create a new block.
   *
   * @return \Drupal\Core\Block\BlockPluginInterface
   *   The block plugin.
   */
  protected abstract function prepareBlock($block_id);

  /**
   * Get the value to use for the submit button.
   *
   * @return TranslatableMarkup
   */
  protected abstract function getSubmitValue();

  /**
   * Form constructor.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @param ContextInterface $context
   *   The context the reaction belongs to.
   *
   * @param string|null $reaction_id
   *   The ID of the blocks reaction the block should be added to.
   *
   * @param string|null $block_id
   *   The ID of the block to show a configuration form for.
   *
   * @return array
   */
  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);

    // If a theme was defined in the query use this theme for the block
    // otherwise use the default theme.
    $theme = $this
      ->getRequest()->query
      ->get('theme', $this->themeHandler
      ->getDefault());

    // Some blocks require the theme name in the form state like Site Branding
    $form_state
      ->set('block_theme', $theme);

    // Some blocks require contexts, set a temporary value with gathered
    // contextual values.
    $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',
      ],
    ];

    // Remove ajax from submit, if this is not ajax request.
    if (!$this->request
      ->isXmlHttpRequest()) {
      unset($form['actions']['submit']['#ajax']);
    }

    // Disable cache on form to prevent ajax forms from failing.
    $form_state
      ->disableCache();
    return $form;
  }

  /**
   * Form submission handler.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $settings = (new FormState())
      ->setValues($form_state
      ->getValue('settings'));

    // Call the plugin submit handler.
    $this->block
      ->submitConfigurationForm($form, $settings);

    // Update the original form values.
    $form_state
      ->setValue('settings', $settings
      ->getValues());

    // Add available contexts if this is a context aware block.
    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(),
    ]);

    // Add/Update the block.
    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(),
    ]));
  }

  /**
   * Handle when the form is submitted trough AJAX.
   *
   * @return AjaxResponse
   */
  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());

      // Remove any previously added error messages.
      $response
        ->addCommand(new RemoveCommand('#drupal-modal .messages--error'));

      // Replace old form with new one and with error message.
      $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;
  }

  /**
   * Get a list of regions for the select list.
   *
   * @param string $theme
   *   The theme to get a list of regions for.
   *
   * @param string $show
   *   What type of regions that should be returned, defaults to all regions.
   *
   * @return array
   */
  protected function getThemeRegionOptions($theme, $show = REGIONS_ALL) {
    $regions = system_region_list($theme, $show);
    foreach ($regions as $region => $title) {
      $regions[$region] = $title;
    }
    return $regions;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AjaxFormTrait::getAjaxAttributes public static function Gets attributes for use with an AJAX modal.
AjaxFormTrait::getAjaxButtonAttributes public static function Gets attributes for use with an add button AJAX modal.
BlockFormBase::$block protected property The plugin being configured.
BlockFormBase::$blockManager protected property The block manager.
BlockFormBase::$context protected property The context entity the reaction belongs to.
BlockFormBase::$contextManager protected property
BlockFormBase::$contextReactionManager protected property
BlockFormBase::$contextRepository protected property
BlockFormBase::$formBuilder protected property
BlockFormBase::$reaction protected property The blocks reaction this block should be added to.
BlockFormBase::$request protected property
BlockFormBase::$themeHandler protected property
BlockFormBase::buildForm public function Form constructor. Overrides FormInterface::buildForm
BlockFormBase::create public static function Instantiates a new instance of this class. Overrides FormBase::create
BlockFormBase::getSubmitValue abstract protected function Get the value to use for the submit button. 2
BlockFormBase::getThemeRegionOptions protected function Get a list of regions for the select list.
BlockFormBase::prepareBlock abstract protected function Prepares the block plugin based on the block ID. 2
BlockFormBase::submitForm public function Form submission handler. Overrides FormInterface::submitForm
BlockFormBase::submitFormAjax public function Handle when the form is submitted trough AJAX.
BlockFormBase::__construct public function Constructs a new VariantPluginFormBase.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 1
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 1
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
FormBase::validateForm public function Form validation handler. Overrides FormInterface::validateForm 62
FormInterface::getFormId public function Returns a unique string identifying the form. 236
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.