Completed
Push — 8.x-1.x ( 563420...b8d656 )
by Janez
02:43
created

WidgetBase::runWidgetValidators()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 12
rs 9.4285
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
   * @parem \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $selection_storage
86
   *   The selection storage.
87
   */
88 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...
89
    parent::__construct($configuration, $plugin_id, $plugin_definition);
90
    $this->eventDispatcher = $event_dispatcher;
91
    $this->entityTypeManager = $entity_type_manager;
92
    $this->validationManager = $validation_manager;
93
    $this->setConfiguration($configuration);
94
  }
95
96
  /**
97
   * {@inheritdoc}
98
   */
99 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...
100
    return new static(
101
      $configuration,
102
      $plugin_id,
103
      $plugin_definition,
104
      $container->get('event_dispatcher'),
105
      $container->get('entity_type.manager'),
106
      $container->get('plugin.manager.entity_browser.widget_validation')
107
    );
108
  }
109
110
  /**
111
   * {@inheritdoc}
112
   */
113
  public function defaultConfiguration() {
114
    return [];
115
  }
116
117
  /**
118
   * {@inheritdoc}
119
   */
120
  public function getConfiguration() {
121
    return [
122
      'settings' => array_diff_key(
123
        $this->configuration,
124
        ['entity_browser_id' => 0]
125
      ),
126
      'uuid' => $this->uuid(),
127
      'weight' => $this->getWeight(),
128
      'label' => $this->label(),
129
      'id' => $this->id(),
130
    ];
131
  }
132
133
  /**
134
   * {@inheritdoc}
135
   */
136
  public function setConfiguration(array $configuration) {
137
    $configuration += [
138
      'settings' => [],
139
      'uuid' => '',
140
      'weight' => '',
141
      'label' => '',
142
      'id' => '',
143
    ];
144
145
    $this->configuration = $configuration['settings'] + $this->defaultConfiguration();
146
    $this->label = $configuration['label'];
147
    $this->weight = $configuration['weight'];
148
    $this->uuid = $configuration['uuid'];
149
    $this->id = $configuration['id'];
150
  }
151
152
  /**
153
   * {@inheritdoc}
154
   */
155
  public function calculateDependencies() {
156
    return [];
157
  }
158
159
  /**
160
   * {@inheritdoc}
161
   */
162
  public function id() {
163
    return $this->id;
164
  }
165
166
  /**
167
   * {@inheritdoc}
168
   */
169
  public function uuid() {
170
    return $this->uuid;
171
  }
172
173
  /**
174
   * {@inheritdoc}
175
   */
176
  public function label() {
177
    return $this->label;
178
  }
179
180
  /**
181
   * {@inheritdoc}
182
   */
183
  public function setLabel($label) {
184
    $this->label = $label;
185
    return $this;
186
  }
187
188
  /**
189
   * {@inheritdoc}
190
   */
191
  public function getWeight() {
192
    return $this->weight;
193
  }
194
195
  /**
196
   * {@inheritdoc}
197
   */
198
  public function setWeight($weight) {
199
    $this->weight = $weight;
200
    return $this;
201
  }
202
203
  /**
204
   * Prepares the entities without saving them.
205
   *
206
   * We need this method when we want to validate or perform other operations
207
   * before submit.
208
   *
209
   * @param \Drupal\Core\Form\FormStateInterface $form_state
210
   *   The form state object.
211
   *
212
   * @return \Drupal\Core\Entity\EntityInterface[]
213
   *   Array of entities.
214
   */
215
  abstract protected function prepareEntities(FormStateInterface $form_state);
216
217
  /**
218
   * {@inheritdoc}
219
   */
220
  public function validate(array &$form, FormStateInterface $form_state) {
221
    $entities = $this->prepareEntities($form_state);
222
    $validators = $form_state->get(['entity_browser', 'validators']);
223
    if ($validators) {
224
      $violations = $this->runWidgetValidators($entities, $validators);
225
      foreach ($violations as $violation) {
226
        $form_state->setError($form['widget'], $violation->getMessage());
227
      }
228
    }
229
  }
230
231
  /**
232
   * Run widget validators.
233
   *
234
   * @param array $entities
235
   *   Array of entity ids to validate.
236
   * @param array $validators
237
   *   Array of widget validator ids.
238
   *
239
   * @return \Symfony\Component\Validator\ConstraintViolationListInterface
240
   *   A list of constraint violations. If the list is empty, validation
241
   *   succeeded.
242
   */
243
  protected function runWidgetValidators(array $entities, $validators = []) {
244
    $violations = new ConstraintViolationList();
245
    foreach ($validators as $validator_id => $options) {
246
      /** @var \Drupal\entity_browser\WidgetValidationInterface $widget_validator */
247
      $widget_validator = $this->validationManager->createInstance($validator_id, []);
248
      if ($widget_validator) {
249
        $violations->addAll($widget_validator->validate($entities, $options));
250
      }
251
    }
252
253
    return $violations;
254
  }
255
256
  /**
257
   * {@inheritdoc}
258
   */
259
  public function submit(array &$element, array &$form, FormStateInterface $form_state) {}
260
261
  /**
262
   * Dispatches event that informs all subscribers about new selected entities.
263
   *
264
   * @param array $entities
265
   *   Array of entities.
266
   */
267
  protected function selectEntities(array $entities, FormStateInterface $form_state) {
268
    $selected_entities = &$form_state->get(['entity_browser', 'selected_entities']);
269
    $selected_entities = array_merge($selected_entities, $entities);
270
271
    $this->eventDispatcher->dispatch(
272
      Events::SELECTED,
273
      new EntitySelectionEvent(
274
        $this->configuration['entity_browser_id'],
275
        $form_state->get(['entity_browser', 'instance_uuid']),
276
        $entities
277
      ));
278
  }
279
280
}
281