Completed
Push — 8.x-1.x ( 729d7d...e0281d )
by Janez
02:47
created

WidgetBase::label()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Drupal\entity_browser;
4
5
use Drupal\Core\Entity\EntityTypeManagerInterface;
6
use Drupal\Core\Plugin\PluginBase;
7
use Drupal\Core\Form\FormStateInterface;
8
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
9
use Drupal\entity_browser\Events\EntitySelectionEvent;
10
use Drupal\entity_browser\Events\Events;
11
use Symfony\Component\DependencyInjection\ContainerInterface;
12
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
13
use Symfony\Component\Validator\ConstraintViolationList;
14
15
/**
16
 * Base class for widget plugins.
17
 */
18
abstract class WidgetBase extends PluginBase implements WidgetInterface, ContainerFactoryPluginInterface {
19
20
  use PluginConfigurationFormTrait;
21
22
  /**
23
   * Plugin id.
24
   *
25
   * @var string
26
   */
27
  protected $id;
28
29
  /**
30
   * Plugin uuid.
31
   *
32
   * @var string
33
   */
34
  protected $uuid;
35
  /**
36
   * Plugin label.
37
   *
38
   * @var string
39
   */
40
  protected $label;
41
42
  /**
43
   * Plugin weight.
44
   *
45
   * @var int
46
   */
47
  protected $weight;
48
49
  /**
50
   * Event dispatcher service.
51
   *
52
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
53
   */
54
  protected $eventDispatcher;
55
56
  /**
57
   * Entity type manager service.
58
   *
59
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
60
   */
61
  protected $entityTypeManager;
62
63
  /**
64
   * The Widget Validation Manager service.
65
   *
66
   * @var \Drupal\entity_browser\WidgetValidationManager
67
   */
68
  protected $validationManager;
69
70
  /**
71
   * WidgetBase constructor.
72
   *
73
   * @param array $configuration
74
   *   A configuration array containing information about the plugin instance.
75
   * @param string $plugin_id
76
   *   The plugin_id for the plugin instance.
77
   * @param mixed $plugin_definition
78
   *   The plugin implementation definition.
79
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
80
   *   Event dispatcher service.
81
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
82
   *   The entity type manager service.
83
   * @param \Drupal\entity_browser\WidgetValidationManager $validation_manager
84
   *   The Widget Validation Manager service.
85
   */
86 View Code Duplication
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, EntityTypeManagerInterface $entity_type_manager, WidgetValidationManager $validation_manager) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
    parent::__construct($configuration, $plugin_id, $plugin_definition);
88
    $this->eventDispatcher = $event_dispatcher;
89
    $this->entityTypeManager = $entity_type_manager;
90
    $this->validationManager = $validation_manager;
91
    $this->setConfiguration($configuration);
92
  }
93
94
  /**
95
   * {@inheritdoc}
96
   */
97 View Code Duplication
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
98
    return new static(
99
      $configuration,
100
      $plugin_id,
101
      $plugin_definition,
102
      $container->get('event_dispatcher'),
103
      $container->get('entity_type.manager'),
104
      $container->get('plugin.manager.entity_browser.widget_validation')
105
    );
106
  }
107
108
  /**
109
   * {@inheritdoc}
110
   */
111
  public function getForm(array &$original_form, FormStateInterface $form_state, array $additional_widget_parameters) {
112
    // Allow configuration overrides at runtime based on form state to enable
113
    // use cases where the instance of a widget may have contextual
114
    // configuration like field settings. "widget_context" doesn't have to be
115
    // used in this way, if a widget doesn't want its default configuration
116
    // overwritten it can not call this method and implement its own logic.
117
    foreach ($this->defaultConfiguration() as $key => $value) {
118
      if ($form_state->has(['entity_browser', 'widget_context', $key]) && isset($this->configuration[$key])) {
119
        $this->configuration[$key] = $form_state->get(['entity_browser', 'widget_context', $key]);
120
      }
121
    }
122
123
    $form['actions'] = [
0 ignored issues
show
Coding Style Comprehensibility introduced by
$form was never initialized. Although not strictly required by PHP, it is generally a good practice to add $form = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
124
      '#type' => 'actions',
125
      'submit' => [
126
        '#type' => 'submit',
127
        '#value' => $this->configuration['submit_text'],
128
        '#eb_widget_main_submit' => TRUE,
129
        '#attributes' => ['class' => ['is-entity-browser-submit']],
130
      ],
131
    ];
132
133
    return $form;
134
  }
135
136
137
  /**
138
   * {@inheritdoc}
139
   */
140
  public function defaultConfiguration() {
141
    return [
142
      'submit_text' => $this->t('Select entities'),
143
    ];
144
  }
145
146
147
  /**
148
   * {@inheritdoc}
149
   */
150
  public function getConfiguration() {
151
    return [
152
      'settings' => array_diff_key(
153
        $this->configuration,
154
        ['entity_browser_id' => 0]
155
      ),
156
      'uuid' => $this->uuid(),
157
      'weight' => $this->getWeight(),
158
      'label' => $this->label(),
159
      'id' => $this->id(),
160
    ];
161
  }
162
163
  /**
164
   * {@inheritdoc}
165
   */
166
  public function setConfiguration(array $configuration) {
167
    $configuration += [
168
      'settings' => [],
169
      'uuid' => '',
170
      'weight' => '',
171
      'label' => '',
172
      'id' => '',
173
    ];
174
175
    $this->configuration = $configuration['settings'] + $this->defaultConfiguration();
176
    $this->label = $configuration['label'];
177
    $this->weight = $configuration['weight'];
178
    $this->uuid = $configuration['uuid'];
179
    $this->id = $configuration['id'];
180
  }
181
182
  /**
183
   * {@inheritdoc}
184
   */
185
  public function calculateDependencies() {
186
    return [];
187
  }
188
189
  /**
190
   * {@inheritdoc}
191
   */
192
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
193
    $form['submit_text'] = [
194
      '#type' => 'textfield',
195
      '#title' => $this->t('Submit button text'),
196
      '#default_value' => $this->configuration['submit_text'],
197
    ];
198
199
    return $form;
200
  }
201
202
  /**
203
   * {@inheritdoc}
204
   */
205
  public function id() {
206
    return $this->id;
207
  }
208
209
  /**
210
   * {@inheritdoc}
211
   */
212
  public function uuid() {
213
    return $this->uuid;
214
  }
215
216
  /**
217
   * {@inheritdoc}
218
   */
219
  public function label() {
220
    return $this->label;
221
  }
222
223
  /**
224
   * {@inheritdoc}
225
   */
226
  public function setLabel($label) {
227
    $this->label = $label;
228
    return $this;
229
  }
230
231
  /**
232
   * {@inheritdoc}
233
   */
234
  public function getWeight() {
235
    return $this->weight;
236
  }
237
238
  /**
239
   * {@inheritdoc}
240
   */
241
  public function setWeight($weight) {
242
    $this->weight = $weight;
243
    return $this;
244
  }
245
246
  /**
247
   * Prepares the entities without saving them.
248
   *
249
   * We need this method when we want to validate or perform other operations
250
   * before submit.
251
   *
252
   * @param array $form
253
   *   Complete form.
254
   * @param \Drupal\Core\Form\FormStateInterface $form_state
255
   *   The form state object.
256
   *
257
   * @return \Drupal\Core\Entity\EntityInterface[]
258
   *   Array of entities.
259
   */
260
  abstract protected function prepareEntities(array $form, FormStateInterface $form_state);
261
262
  /**
263
   * {@inheritdoc}
264
   */
265
  public function validate(array &$form, FormStateInterface $form_state) {
266
    $entities = $this->prepareEntities($form, $form_state);
267
    $validators = $form_state->get(['entity_browser', 'validators']);
268
    if ($validators) {
269
      $violations = $this->runWidgetValidators($entities, $validators);
270
      foreach ($violations as $violation) {
271
        $form_state->setError($form['widget'], $violation->getMessage());
272
      }
273
    }
274
  }
275
276
  /**
277
   * Run widget validators.
278
   *
279
   * @param array $entities
280
   *   Array of entity ids to validate.
281
   * @param array $validators
282
   *   Array of widget validator ids.
283
   *
284
   * @return \Symfony\Component\Validator\ConstraintViolationListInterface
285
   *   A list of constraint violations. If the list is empty, validation
286
   *   succeeded.
287
   */
288
  protected function runWidgetValidators(array $entities, $validators = []) {
289
    $violations = new ConstraintViolationList();
290
    foreach ($validators as $validator_id => $options) {
291
      /** @var \Drupal\entity_browser\WidgetValidationInterface $widget_validator */
292
      $widget_validator = $this->validationManager->createInstance($validator_id, []);
293
      if ($widget_validator) {
294
        $violations->addAll($widget_validator->validate($entities, $options));
295
      }
296
    }
297
298
    return $violations;
299
  }
300
301
  /**
302
   * {@inheritdoc}
303
   */
304
  public function submit(array &$element, array &$form, FormStateInterface $form_state) {}
305
306
  /**
307
   * Dispatches event that informs all subscribers about new selected entities.
308
   *
309
   * @param array $entities
310
   *   Array of entities.
311
   */
312
  protected function selectEntities(array $entities, FormStateInterface $form_state) {
313
    $selected_entities = &$form_state->get(['entity_browser', 'selected_entities']);
314
    $selected_entities = array_merge($selected_entities, $entities);
315
316
    $this->eventDispatcher->dispatch(
317
      Events::SELECTED,
318
      new EntitySelectionEvent(
319
        $this->configuration['entity_browser_id'],
320
        $form_state->get(['entity_browser', 'instance_uuid']),
321
        $entities
322
      ));
323
  }
324
325
}
326