Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / modules / layout_builder / src / Form / ConfigureBlockFormBase.php
1 <?php
2
3 namespace Drupal\layout_builder\Form;
4
5 use Drupal\Component\Uuid\UuidInterface;
6 use Drupal\Core\Block\BlockManagerInterface;
7 use Drupal\Core\Block\BlockPluginInterface;
8 use Drupal\Core\DependencyInjection\ClassResolverInterface;
9 use Drupal\Core\Form\FormBase;
10 use Drupal\Core\Form\FormStateInterface;
11 use Drupal\Core\Form\SubformState;
12 use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
13 use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait;
14 use Drupal\Core\Plugin\ContextAwarePluginInterface;
15 use Drupal\Core\Plugin\PluginFormFactoryInterface;
16 use Drupal\Core\Plugin\PluginWithFormsInterface;
17 use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
18 use Drupal\layout_builder\Controller\LayoutRebuildTrait;
19 use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
20 use Drupal\layout_builder\SectionComponent;
21 use Drupal\layout_builder\SectionStorageInterface;
22 use Symfony\Component\DependencyInjection\ContainerInterface;
23
24 /**
25  * Provides a base form for configuring a block.
26  *
27  * @internal
28  */
29 abstract class ConfigureBlockFormBase extends FormBase {
30
31   use AjaxFormHelperTrait;
32   use ContextAwarePluginAssignmentTrait;
33   use LayoutBuilderContextTrait;
34   use LayoutRebuildTrait;
35
36   /**
37    * The plugin being configured.
38    *
39    * @var \Drupal\Core\Block\BlockPluginInterface
40    */
41   protected $block;
42
43   /**
44    * The layout tempstore repository.
45    *
46    * @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface
47    */
48   protected $layoutTempstoreRepository;
49
50   /**
51    * The block manager.
52    *
53    * @var \Drupal\Core\Block\BlockManagerInterface
54    */
55   protected $blockManager;
56
57   /**
58    * The UUID generator.
59    *
60    * @var \Drupal\Component\Uuid\UuidInterface
61    */
62   protected $uuidGenerator;
63
64   /**
65    * The plugin form manager.
66    *
67    * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
68    */
69   protected $pluginFormFactory;
70
71   /**
72    * The field delta.
73    *
74    * @var int
75    */
76   protected $delta;
77
78   /**
79    * The current region.
80    *
81    * @var string
82    */
83   protected $region;
84
85   /**
86    * The UUID of the component.
87    *
88    * @var string
89    */
90   protected $uuid;
91
92   /**
93    * The section storage.
94    *
95    * @var \Drupal\layout_builder\SectionStorageInterface
96    */
97   protected $sectionStorage;
98
99   /**
100    * Constructs a new block form.
101    *
102    * @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository
103    *   The layout tempstore repository.
104    * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository
105    *   The context repository.
106    * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
107    *   The block manager.
108    * @param \Drupal\Component\Uuid\UuidInterface $uuid
109    *   The UUID generator.
110    * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
111    *   The class resolver.
112    * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $plugin_form_manager
113    *   The plugin form manager.
114    */
115   public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, ContextRepositoryInterface $context_repository, BlockManagerInterface $block_manager, UuidInterface $uuid, ClassResolverInterface $class_resolver, PluginFormFactoryInterface $plugin_form_manager) {
116     $this->layoutTempstoreRepository = $layout_tempstore_repository;
117     $this->contextRepository = $context_repository;
118     $this->blockManager = $block_manager;
119     $this->uuidGenerator = $uuid;
120     $this->classResolver = $class_resolver;
121     $this->pluginFormFactory = $plugin_form_manager;
122   }
123
124   /**
125    * {@inheritdoc}
126    */
127   public static function create(ContainerInterface $container) {
128     return new static(
129       $container->get('layout_builder.tempstore_repository'),
130       $container->get('context.repository'),
131       $container->get('plugin.manager.block'),
132       $container->get('uuid'),
133       $container->get('class_resolver'),
134       $container->get('plugin_form.factory')
135     );
136   }
137
138   /**
139    * Builds the form for the block.
140    *
141    * @param array $form
142    *   An associative array containing the structure of the form.
143    * @param \Drupal\Core\Form\FormStateInterface $form_state
144    *   The current state of the form.
145    * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
146    *   The section storage being configured.
147    * @param int $delta
148    *   The delta of the section.
149    * @param \Drupal\layout_builder\SectionComponent $component
150    *   The section component containing the block.
151    *
152    * @return array
153    *   The form array.
154    */
155   public function doBuildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL, $delta = NULL, SectionComponent $component = NULL) {
156     $this->sectionStorage = $section_storage;
157     $this->delta = $delta;
158     $this->uuid = $component->getUuid();
159     $this->block = $component->getPlugin();
160
161     $form_state->setTemporaryValue('gathered_contexts', $this->getAvailableContexts($section_storage));
162
163     // @todo Remove once https://www.drupal.org/node/2268787 is resolved.
164     $form_state->set('block_theme', $this->config('system.theme')->get('default'));
165
166     $form['#tree'] = TRUE;
167     $form['settings'] = [];
168     $subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
169     $form['settings'] = $this->getPluginForm($this->block)->buildConfigurationForm($form['settings'], $subform_state);
170
171     $form['actions']['submit'] = [
172       '#type' => 'submit',
173       '#value' => $this->submitLabel(),
174       '#button_type' => 'primary',
175     ];
176     if ($this->isAjax()) {
177       $form['actions']['submit']['#ajax']['callback'] = '::ajaxSubmit';
178     }
179
180     return $form;
181   }
182
183   /**
184    * Returns the label for the submit button.
185    *
186    * @return string
187    *   Submit label.
188    */
189   abstract protected function submitLabel();
190
191   /**
192    * {@inheritdoc}
193    */
194   public function validateForm(array &$form, FormStateInterface $form_state) {
195     $subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
196     $this->getPluginForm($this->block)->validateConfigurationForm($form['settings'], $subform_state);
197   }
198
199   /**
200    * {@inheritdoc}
201    */
202   public function submitForm(array &$form, FormStateInterface $form_state) {
203     // Call the plugin submit handler.
204     $subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
205     $this->getPluginForm($this->block)->submitConfigurationForm($form, $subform_state);
206
207     // If this block is context-aware, set the context mapping.
208     if ($this->block instanceof ContextAwarePluginInterface) {
209       $this->block->setContextMapping($subform_state->getValue('context_mapping', []));
210     }
211
212     $configuration = $this->block->getConfiguration();
213
214     $section = $this->sectionStorage->getSection($this->delta);
215     $section->getComponent($this->uuid)->setConfiguration($configuration);
216
217     $this->layoutTempstoreRepository->set($this->sectionStorage);
218     $form_state->setRedirectUrl($this->sectionStorage->getLayoutBuilderUrl());
219   }
220
221   /**
222    * {@inheritdoc}
223    */
224   protected function successfulAjaxSubmit(array $form, FormStateInterface $form_state) {
225     return $this->rebuildAndClose($this->sectionStorage);
226   }
227
228   /**
229    * Retrieves the plugin form for a given block.
230    *
231    * @param \Drupal\Core\Block\BlockPluginInterface $block
232    *   The block plugin.
233    *
234    * @return \Drupal\Core\Plugin\PluginFormInterface
235    *   The plugin form for the block.
236    */
237   protected function getPluginForm(BlockPluginInterface $block) {
238     if ($block instanceof PluginWithFormsInterface) {
239       return $this->pluginFormFactory->createInstance($block, 'configure');
240     }
241     return $block;
242   }
243
244 }