Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / entity_browser / src / Form / EntityBrowserForm.php
1 <?php
2
3 namespace Drupal\entity_browser\Form;
4
5 use Drupal\Component\Uuid\UuidInterface;
6 use Drupal\Core\Config\ConfigException;
7 use Drupal\Core\Form\FormBase;
8 use Drupal\Core\Form\FormStateInterface;
9 use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
10 use Drupal\entity_browser\DisplayAjaxInterface;
11 use Drupal\entity_browser\EntityBrowserFormInterface;
12 use Drupal\entity_browser\EntityBrowserInterface;
13 use Symfony\Component\DependencyInjection\ContainerInterface;
14 use Drupal\Core\Render\RendererInterface;
15
16 /**
17  * The entity browser form.
18  */
19 class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
20
21   /**
22    * UUID generator service.
23    *
24    * @var \Drupal\Component\Uuid\UuidInterface
25    */
26   protected $uuidGenerator;
27
28   /**
29    * The entity browser object.
30    *
31    * @var \Drupal\entity_browser\EntityBrowserInterface
32    */
33   protected $entityBrowser;
34
35   /**
36    * The entity browser selection storage.
37    *
38    * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
39    */
40   protected $selectionStorage;
41
42   /**
43    * The renderer service.
44    *
45    * @var \Drupal\Core\Render\RendererInterface
46    */
47   protected $renderer;
48
49   /**
50    * Constructs a EntityBrowserForm object.
51    *
52    * @param \Drupal\Component\Uuid\UuidInterface $uuid_generator
53    *   The UUID generator service.
54    * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $selection_storage
55    *   Selection storage.
56    * @param \Drupal\Core\Render\RendererInterface $renderer
57    *   The renderer service.
58    */
59   public function __construct(UuidInterface $uuid_generator, KeyValueStoreExpirableInterface $selection_storage, RendererInterface $renderer) {
60     $this->uuidGenerator = $uuid_generator;
61     $this->selectionStorage = $selection_storage;
62     $this->renderer = $renderer;
63   }
64
65   /**
66    * {@inheritdoc}
67    */
68   public static function create(ContainerInterface $container) {
69     return new static(
70       $container->get('uuid'),
71       $container->get('entity_browser.selection_storage'),
72       $container->get('renderer')
73     );
74   }
75
76   /**
77    * {@inheritdoc}
78    */
79   public function getFormId() {
80     return 'entity_browser_' . $this->entityBrowser->id() . '_form';
81   }
82
83   /**
84    * {@inheritdoc}
85    */
86   public function setEntityBrowser(EntityBrowserInterface $entity_browser) {
87     $this->entityBrowser = $entity_browser;
88   }
89
90   /**
91    * {@inheritdoc}
92    */
93   public function getEntityBrowser() {
94     return $this->entityBrowser;
95   }
96
97   /**
98    * Initializes form state.
99    *
100    * @param \Drupal\Core\Form\FormStateInterface $form_state
101    *   Form state object.
102    */
103   protected function init(FormStateInterface $form_state) {
104     // Flag that this form has been initialized.
105     $form_state->set('entity_form_initialized', TRUE);
106     if ($this->getRequest()->query->has('uuid')) {
107       $form_state->set(['entity_browser', 'instance_uuid'], $this->getRequest()->query->get('uuid'));
108     }
109     else {
110       $form_state->set(['entity_browser', 'instance_uuid'], $this->uuidGenerator->generate());
111     }
112     $form_state->set(['entity_browser', 'selected_entities'], []);
113     $form_state->set(['entity_browser', 'validators'], []);
114     $form_state->set(['entity_browser', 'widget_context'], []);
115     $form_state->set(['entity_browser', 'selection_completed'], FALSE);
116
117     // Initialize form state with persistent data, if present.
118     if ($storage = $this->selectionStorage->get($form_state->get(['entity_browser', 'instance_uuid']))) {
119       foreach ($storage as $key => $value) {
120         $form_state->set(['entity_browser', $key], $value);
121       }
122     }
123   }
124
125   /**
126    * {@inheritdoc}
127    */
128   public function buildForm(array $form, FormStateInterface $form_state) {
129     // During the initial form build, add this form object to the form state and
130     // allow for initial preparation before form building and processing.
131     if (!$form_state->has('entity_form_initialized')) {
132       $this->init($form_state);
133     }
134
135     $this->isFunctionalForm();
136
137     $form['#attributes']['class'][] = 'entity-browser-form';
138     if (!empty($form_state->get(['entity_browser', 'instance_uuid']))) {
139       $form['#attributes']['data-entity-browser-uuid'] = $form_state->get(['entity_browser', 'instance_uuid']);
140     }
141     $form['#browser_parts'] = [
142       'widget_selector' => 'widget_selector',
143       'widget' => 'widget',
144       'selection_display' => 'selection_display',
145     ];
146
147     if (!($current_widget_id = $this->getCurrentWidget($form_state))) {
148       drupal_set_message($this->t('No widgets are available.'), 'warning');
149       return $form;
150     }
151
152     $this->entityBrowser
153       ->getWidgetSelector()
154       ->setDefaultWidget($current_widget_id);
155     $form[$form['#browser_parts']['widget_selector']] = $this->entityBrowser
156       ->getWidgetSelector()
157       ->getForm($form, $form_state);
158
159     $widget = $this->entityBrowser->getWidget($current_widget_id);
160     if ($widget->access()->isAllowed()) {
161       $form[$form['#browser_parts']['widget']] = $widget->getForm($form, $form_state, $this->entityBrowser->getAdditionalWidgetParameters());
162     }
163     else {
164       drupal_set_message($this->t('Access to the widget forbidden.'), 'warning');
165     }
166
167     // Add cache access cache metadata from the widgets to the form directly as
168     // it is affected.
169     foreach ($this->entityBrowser->getWidgets() as $widget) {
170       /** @var \Drupal\entity_browser\WidgetInterface $widget */
171       $this->renderer->addCacheableDependency($form, $widget->access());
172     }
173
174     $form[$form['#browser_parts']['selection_display']] = $this->entityBrowser
175       ->getSelectionDisplay()
176       ->getForm($form, $form_state);
177
178     if ($this->entityBrowser->getDisplay() instanceof DisplayAjaxInterface) {
179       $this->entityBrowser->getDisplay()->addAjax($form);
180     }
181
182     $form['#attached']['library'][] = 'entity_browser/entity_browser';
183
184     return $form;
185   }
186
187   /**
188    * Check if entity browser with selected configuration combination can work.
189    */
190   protected function isFunctionalForm() {
191     /** @var \Drupal\entity_browser\WidgetInterface $widget */
192     foreach ($this->entityBrowser->getWidgets() as $widget) {
193       /** @var \Drupal\entity_browser\SelectionDisplayInterface $selectionDisplay */
194       $selectionDisplay = $this->entityBrowser->getSelectionDisplay();
195
196       if ($widget->requiresJsCommands() && !$selectionDisplay->supportsJsCommands()) {
197         throw new ConfigException('Used entity browser selection display cannot work in combination with settings defined for used selection widget.');
198       }
199     }
200   }
201
202   /**
203    * {@inheritdoc}
204    */
205   public function validateForm(array &$form, FormStateInterface $form_state) {
206     $this->entityBrowser->getWidgetSelector()->validate($form, $form_state);
207     $this->entityBrowser->getWidgets()->get($this->getCurrentWidget($form_state))->validate($form, $form_state);
208     $this->entityBrowser->getSelectionDisplay()->validate($form, $form_state);
209   }
210
211   /**
212    * {@inheritdoc}
213    */
214   public function submitForm(array &$form, FormStateInterface $form_state) {
215     $original_widget = $this->getCurrentWidget($form_state);
216     if ($new_widget = $this->entityBrowser->getWidgetSelector()->submit($form, $form_state)) {
217       $this->setCurrentWidget($new_widget, $form_state);
218     }
219
220     // Only call widget submit if we didn't change the widget.
221     if ($original_widget == $this->getCurrentWidget($form_state)) {
222       $this->entityBrowser
223         ->getWidgets()
224         ->get($this->getCurrentWidget($form_state))
225         ->submit($form[$form['#browser_parts']['widget']], $form, $form_state);
226
227       $this->entityBrowser
228         ->getSelectionDisplay()
229         ->submit($form, $form_state);
230     }
231
232     if (!$this->isSelectionCompleted($form_state)) {
233       $form_state->setRebuild();
234     }
235     else {
236       $this->entityBrowser->getDisplay()->selectionCompleted($this->getSelectedEntities($form_state));
237     }
238   }
239
240   /**
241    * Returns the widget that is currently selected.
242    *
243    * @param \Drupal\Core\Form\FormStateInterface $form_state
244    *   The current state of the form.
245    *
246    * @return string
247    *   ID of currently selected widget.
248    */
249   protected function getCurrentWidget(FormStateInterface $form_state) {
250     // Do not use has() as that returns TRUE if the value is NULL.
251     if (!$form_state->get('entity_browser_current_widget')) {
252       $form_state->set('entity_browser_current_widget', $this->entityBrowser->getFirstWidget());
253     }
254
255     return $form_state->get('entity_browser_current_widget');
256   }
257
258   /**
259    * Sets widget that is currently active.
260    *
261    * @param string $widget
262    *   New active widget UUID.
263    * @param \Drupal\Core\Form\FormStateInterface $form_state
264    *   Form state.
265    */
266   protected function setCurrentWidget($widget, FormStateInterface $form_state) {
267     $form_state->set('entity_browser_current_widget', $widget);
268   }
269
270   /**
271    * Indicates selection is done.
272    *
273    * @param \Drupal\Core\Form\FormStateInterface $form_state
274    *   Form state.
275    *
276    * @return bool
277    *   Indicates selection is done.
278    */
279   protected function isSelectionCompleted(FormStateInterface $form_state) {
280     return (bool) $form_state->get(['entity_browser', 'selection_completed']);
281   }
282
283   /**
284    * Returns currently selected entities.
285    *
286    * @param \Drupal\Core\Form\FormStateInterface $form_state
287    *   Form state.
288    *
289    * @return \Drupal\Core\Entity\EntityInterface[]
290    *   Array of currently selected entities.
291    */
292   protected function getSelectedEntities(FormStateInterface $form_state) {
293     return $form_state->get(['entity_browser', 'selected_entities']);
294   }
295
296 }