Completed
Pull Request — 8.x-1.x (#153)
by
unknown
02:27
created

EntityBrowserForm::isFunctionalForm()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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