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

EntityBrowserForm::isFunctionalForm()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
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
    $current_widget_config = $this->entity_browser
153
      ->getWidgets()
154
      ->get($this->getCurrentWidget($form_state))
155
      ->getConfiguration();
156
157
    if ($current_widget_config['settings']['auto_select']) {
158
      /** @var \Drupal\entity_browser\SelectionDisplayInterface $selectionDisplay */
159
      $selectionDisplay = $this->entity_browser
160
        ->getSelectionDisplay();
161
162
      if (!$selectionDisplay->getPluginDefinition()['jsCommands']) {
163
        throw new ConfigException('Used entity browser selection display cannot work in combination with settings defined for used selection widget.');
164
      }
165
    }
166
  }
167
168
  /**
169
   * {@inheritdoc}
170
   */
171
  public function validateForm(array &$form, FormStateInterface $form_state) {
172
    $this->entity_browser->getWidgetSelector()->validate($form, $form_state);
173
    $this->entity_browser->getWidgets()->get($this->getCurrentWidget($form_state))->validate($form, $form_state);
174
    $this->entity_browser->getSelectionDisplay()->validate($form, $form_state);
175
  }
176
177
  /**
178
   * {@inheritdoc}
179
   */
180
  public function submitForm(array &$form, FormStateInterface $form_state) {
181
    $original_widget = $this->getCurrentWidget($form_state);
182
    if ($new_widget = $this->entity_browser->getWidgetSelector()->submit($form, $form_state)) {
183
      $this->setCurrentWidget($new_widget, $form_state);
184
    }
185
186
    // Only call widget submit if we didn't change the widget.
187
    if ($original_widget == $this->getCurrentWidget($form_state)) {
188
      $this->entity_browser
189
        ->getWidgets()
190
        ->get($this->getCurrentWidget($form_state))
191
        ->submit($form[$form['#browser_parts']['widget']], $form, $form_state);
192
193
      $this->entity_browser
194
        ->getSelectionDisplay()
195
        ->submit($form, $form_state);
196
    }
197
198
    if (!$this->isSelectionCompleted($form_state)) {
199
      $form_state->setRebuild();
200
    }
201
    else {
202
      $this->entity_browser->getDisplay()->selectionCompleted($this->getSelectedEntities($form_state));
203
    }
204
  }
205
206
  /**
207
   * Returns the widget that is currently selected.
208
   *
209
   * @param \Drupal\Core\Form\FormStateInterface $form_state
210
   *   The current state of the form.
211
   *
212
   * @return string
213
   *   ID of currently selected widget.
214
   */
215
  protected function getCurrentWidget(FormStateInterface $form_state) {
216
    // Do not use has() as that returns TRUE if the value is NULL.
217
    if (!$form_state->get('entity_browser_current_widget')) {
218
      $form_state->set('entity_browser_current_widget', $this->entity_browser->getFirstWidget());
219
    }
220
221
    return $form_state->get('entity_browser_current_widget');
222
  }
223
224
  /**
225
   * Sets widget that is currently active.
226
   *
227
   * @param string $widget
228
   *   New active widget UUID.
229
   * @param \Drupal\Core\Form\FormStateInterface $form_state
230
   *   Form state.
231
   */
232
  protected function setCurrentWidget($widget, FormStateInterface $form_state) {
233
    $form_state->set('entity_browser_current_widget', $widget);
234
  }
235
236
  /**
237
   * Indicates selection is done.
238
   *
239
   * @param \Drupal\Core\Form\FormStateInterface $form_state
240
   *   Form state.
241
   *
242
   * @return bool
243
   *   Indicates selection is done.
244
   */
245
  protected function isSelectionCompleted(FormStateInterface $form_state) {
246
    return (bool) $form_state->get(['entity_browser', 'selection_completed']);
247
  }
248
249
  /**
250
   * Returns currently selected entities.
251
   *
252
   * @param \Drupal\Core\Form\FormStateInterface $form_state
253
   *   Form state.
254
   *
255
   * @return \Drupal\Core\Entity\EntityInterface[]
256
   *   Array of currently selected entities.
257
   */
258
  protected function getSelectedEntities(FormStateInterface $form_state) {
259
    return $form_state->get(['entity_browser', 'selected_entities']);
260
  }
261
262
}
263