Completed
Push — 8.x-1.x ( 77e186...f7c112 )
by Janez
03:35
created

MultiStepDisplay::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 3
nc 1
nop 6
1
<?php
2
3
namespace Drupal\entity_browser\Plugin\EntityBrowser\SelectionDisplay;
4
5
use Drupal\Core\Entity\EntityManagerInterface;
6
use Drupal\Core\Form\FormStateInterface;
7
use Drupal\entity_browser\FieldWidgetDisplayManager;
8
use Drupal\entity_browser\SelectionDisplayBase;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
10
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
11
12
/**
13
 * Show current selection and delivers selected entities.
14
 *
15
 * @EntityBrowserSelectionDisplay(
16
 *   id = "multi_step_display",
17
 *   label = @Translation("Multi step selection display"),
18
 *   description = @Translation("Show current selection display and delivers selected entities.")
19
 * )
20
 */
21
class MultiStepDisplay extends SelectionDisplayBase {
22
23
  /**
24
   * Field widget display plugin manager.
25
   *
26
   * @var \Drupal\entity_browser\FieldWidgetDisplayManager
27
   */
28
  protected $fieldDisplayManager;
29
30
  /**
31
   * Constructs widget plugin.
32
   *
33
   * @param array $configuration
34
   *   A configuration array containing information about the plugin instance.
35
   * @param string $plugin_id
36
   *   The plugin_id for the plugin instance.
37
   * @param mixed $plugin_definition
38
   *   The plugin implementation definition.
39
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
40
   *   Event dispatcher service.
41
   * @param \Drupal\Core\Entity\EntityManagerInterface
42
   *   Entity manager service.
43
   * @param \Drupal\entity_browser\FieldWidgetDisplayManager $field_display_manager
44
   *   Field widget display plugin manager.
45
   */
46
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, EntityManagerInterface $entity_manager, FieldWidgetDisplayManager $field_display_manager) {
47
    parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher, $entity_manager);
48
    $this->fieldDisplayManager = $field_display_manager;
49
  }
50
51
  /**
52
   * {@inheritdoc}
53
   */
54 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...
55
    return new static(
56
      $configuration,
57
      $plugin_id,
58
      $plugin_definition,
59
      $container->get('event_dispatcher'),
60
      $container->get('entity.manager'),
61
      $container->get('plugin.manager.entity_browser.field_widget_display')
62
    );
63
  }
64
  /**
65
   * {@inheritdoc}
66
   */
67
  public function defaultConfiguration() {
68
    return [
69
      'entity_type' => 'node',
70
      'display' => 'label',
71
      'display_settings' => [],
72
      'select_text' => 'Use selected',
73
    ] + parent::defaultConfiguration();
74
  }
75
76
  /**
77
   * {@inheritdoc}
78
   */
79
  public function getForm(array &$original_form, FormStateInterface $form_state) {
80
    $selected_entities = $form_state->get(['entity_browser', 'selected_entities']);
81
82
    $form = [];
83
    $form['#attached']['library'][] = 'entity_browser/multi_step_display';
84
    $form['selected'] = [
85
      '#theme_wrappers' => ['container'],
86
      '#attributes' => ['class' => ['entities-list']],
87
      '#tree' => TRUE
88
    ];
89
    foreach ($selected_entities as $id => $entity) {
90
      $display_plugin = $this->fieldDisplayManager->createInstance(
91
        $this->configuration['display'],
92
        $this->configuration['display_settings'] + ['entity_type' => $this->configuration['entity_type']]
93
      );
94
      $display = $display_plugin->view($entity);
95
      if (is_string($display)) {
96
        $display = ['#markup' => $display];
97
      }
98
99
      $form['selected']['items_'. $entity->id()] = [
100
        '#theme_wrappers' => ['container'],
101
        '#attributes' => [
102
          'class' => ['item-container'],
103
          'data-entity-id' => $entity->id()
104
        ],
105
        'display' => $display,
106
        'remove_button' => [
107
          '#type' => 'submit',
108
          '#value' => $this->t('Remove'),
109
          '#submit' => [[get_class($this), 'removeItemSubmit']],
110
          '#name' => 'remove_' . $entity->id(),
111
          '#attributes' => [
112
            'data-row-id' => $id,
113
            'data-remove-entity' => 'items_' . $entity->id(),
114
          ]
115
        ],
116
        'weight' => [
117
          '#type' => 'hidden',
118
          '#default_value' => $id,
119
          '#attributes' => ['class' => ['weight']]
120
        ]
121
      ];
122
    }
123
    $form['use_selected'] = [
124
      '#type' => 'submit',
125
      '#value' => $this->t($this->configuration['select_text']),
126
      '#name' => 'use_selected',
127
      '#access' => empty($selected_entities) ? FALSE : TRUE,
128
    ];
129
130
    return $form;
131
  }
132
133
  /**
134
   * Submit callback for remove buttons.
135
   *
136
   * @param array $form
137
   * @param \Drupal\Core\Form\FormStateInterface $form_state
138
   */
139
  public static function removeItemSubmit(array &$form, FormStateInterface $form_state) {
140
    $triggering_element = $form_state->getTriggeringElement();
141
142
    // Remove weight of entity being removed.
143
    $form_state->unsetValue(['selected', $triggering_element['#attributes']['data-remove-entity']]);
144
145
    // Remove entity itself.
146
    $selected_entities = &$form_state->get(['entity_browser', 'selected_entities']);
147
    unset($selected_entities[$triggering_element['#attributes']['data-row-id']]);
148
149
    static::saveNewOrder($form_state);
150
    $form_state->setRebuild();
151
  }
152
153
  /**
154
   * {@inheritdoc}
155
   */
156
  public function submit(array &$form, FormStateInterface $form_state) {
157
    $this->saveNewOrder($form_state);
158
    if ($form_state->getTriggeringElement()['#name'] == 'use_selected') {
159
      $this->selectionDone($form_state);
160
    }
161
  }
162
163
  /**
164
   * Saves new ordering of entities based on weight.
165
   *
166
   * @param FormStateInterface $form_state
167
   *   Form state.
168
   */
169
  public static function saveNewOrder(FormStateInterface $form_state) {
170
    $selected = $form_state->getValue('selected');
171
    if (!empty($selected)) {
172
      $weights = array_column($selected, 'weight');
173
      $selected_entities = $form_state->get(['entity_browser', 'selected_entities']);
174
175
      // If we added new entities to the selection at this step we won't have
176
      // weights for them so we have to fake them.
177
      if (sizeof($weights) < sizeof($selected_entities)) {
178
        for ($new_weigth = (max($weights) + 1); $new_weigth < sizeof($selected_entities); $new_weigth++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
179
          $weights[] = $new_weigth;
180
        }
181
      }
182
183
      $ordered = array_combine($weights, $selected_entities);
184
      ksort($ordered);
185
      $form_state->set(['entity_browser', 'selected_entities'], $ordered);
186
    }
187
  }
188
189
  /**
190
   * {@inheritdoc}
191
   */
192
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
193
    $default_entity_type = $form_state->getValue('entity_type', $this->configuration['entity_type']);
194
    $default_display = $form_state->getValue('display', $this->configuration['display']);
195
    $default_display_settings = $form_state->getValue('display_settings', $this->configuration['display_settings']);
196
    $default_display_settings += ['entity_type' => $default_entity_type];
197
198
    $form['#prefix'] = '<div id="multi-step-form-wrapper">';
199
    $form['#suffix'] = '</div>';
200
201
    $entity_types = [];
202
    foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
203
      /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
204
      $entity_types[$entity_type_id] = $entity_type->getLabel();
205
    }
206
    $form['entity_type'] = [
207
      '#type' => 'select',
208
      '#title' => $this->t('Entity type'),
209
      '#description' => $this->t("Entity browser itself does not need information about entity type being selected. It can actually select entities of different type. However, some of the display plugins need to know which entity type they are operating with. Display plugins that do not need this info will ignore this configuration value."),
210
      '#default_value' => $default_entity_type,
211
      '#options' => $entity_types,
212
      '#ajax' => [
213
        'callback' => [$this, 'updateSettingsAjax'],
214
        'wrapper' => 'multi-step-form-wrapper',
215
      ],
216
    ];
217
218
    $displays = [];
219
    foreach ($this->fieldDisplayManager->getDefinitions() as $display_plugin_id => $definition) {
220
      $entity_type = $this->entityManager->getDefinition($default_entity_type);
221
      if ($this->fieldDisplayManager->createInstance($display_plugin_id)->isApplicable($entity_type)) {
222
        $displays[$display_plugin_id] = $definition['label'];
223
      }
224
    }
225
    $form['display'] = [
226
      '#title' => t('Entity display plugin'),
227
      '#type' => 'select',
228
      '#default_value' => $default_display,
229
      '#options' => $displays,
230
      '#ajax' => [
231
        'callback' => [$this, 'updateSettingsAjax'],
232
        'wrapper' => 'multi-step-form-wrapper',
233
      ],
234
    ];
235
236
    $form['display_settings'] = [
237
      '#type' => 'container',
238
      '#title' => t('Entity display plugin configuration'),
239
      '#tree' => TRUE,
240
    ];
241
    if ($default_display_settings) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $default_display_settings of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
242
      $display_plugin = $this->fieldDisplayManager
243
        ->createInstance($default_display, $default_display_settings);
244
245
      $form['display_settings'] += $display_plugin->settingsForm($form, $form_state);
246
    }
247
    $form['select_text'] = [
248
      '#type' => 'textfield',
249
      '#title' => $this->t('Select button text'),
250
      '#default_value' => $this->configuration['select_text'],
251
      '#description' => $this->t('Text to display on the entity browser select button.'),
252
    ];
253
254
    return $form;
255
  }
256
257
  /**
258
   * Ajax callback that updates multi-step plugin configuration form on AJAX updates.
259
   */
260
  public function updateSettingsAjax(array $form, FormStateInterface $form_state) {
261
    return $form;
262
  }
263
264
}
265