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