1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Contains \Drupal\entity_browser\Plugin\EntityBrowser\SelectionDisplay\NewDisplay. |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
namespace Drupal\entity_browser\Plugin\EntityBrowser\SelectionDisplay; |
8
|
|
|
|
9
|
|
|
use Drupal\Component\Utility\Html; |
10
|
|
|
use Drupal\Component\Utility\NestedArray; |
11
|
|
|
use Drupal\Core\Form\FormStateInterface; |
12
|
|
|
use Drupal\entity_browser\SelectionDisplayBase; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Show current selection and delivers selected entities. |
16
|
|
|
* |
17
|
|
|
* @EntityBrowserSelectionDisplay( |
18
|
|
|
* id = "new_display", |
19
|
|
|
* label = @Translation("New selection display"), |
20
|
|
|
* description = @Translation("Show current selection display and delivers selected entities.") |
21
|
|
|
* ) |
22
|
|
|
*/ |
23
|
|
|
class NewDisplay extends SelectionDisplayBase { |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* {@inheritdoc} |
27
|
|
|
*/ |
28
|
|
|
public function defaultConfiguration() { |
29
|
|
|
return array( |
30
|
|
|
'view' => NULL, |
31
|
|
|
'view_display' => NULL, |
32
|
|
|
) + parent::defaultConfiguration(); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* {@inheritdoc} |
37
|
|
|
*/ |
38
|
|
|
public function getForm(array &$original_form, FormStateInterface $form_state) { |
39
|
|
|
$form = []; |
40
|
|
|
$form['#attached']['library'][] = 'entity_browser/new_display'; |
41
|
|
|
|
42
|
|
|
$selected_entities = $form_state->get(['entity_browser', 'selected_entities']); |
43
|
|
|
$ids = array_keys($selected_entities); |
44
|
|
|
|
45
|
|
|
$hidden_id = Html::getUniqueId('edit-selected-target-id'); |
46
|
|
|
$details_id = Html::getUniqueId('edit-selected'); |
47
|
|
|
|
48
|
|
|
$form += [ |
49
|
|
|
'#id' => $details_id, |
50
|
|
|
'#type' => 'details', |
51
|
|
|
'#open' => !empty($ids), |
52
|
|
|
'target_id' => [ |
53
|
|
|
'#type' => 'hidden', |
54
|
|
|
'#id' => $hidden_id, |
55
|
|
|
// We need to repeat ID here as it is otherwise skipped when rendering. |
56
|
|
|
'#attributes' => ['id' => $hidden_id], |
57
|
|
|
'#default_value' => $ids, |
58
|
|
|
// #ajax is officially not supported for hidden elements but if we |
59
|
|
|
// specify event manually it works. |
60
|
|
|
'#ajax' => [ |
61
|
|
|
'callback' => [get_class($this), 'updateWidgetCallback'], |
62
|
|
|
'wrapper' => $details_id, |
63
|
|
|
'event' => 'entity_browser_selected_updated', |
64
|
|
|
], |
65
|
|
|
], |
66
|
|
|
]; |
67
|
|
|
|
68
|
|
|
$form['current'] = [ |
69
|
|
|
'#theme_wrappers' => ['container'], |
70
|
|
|
'#attributes' => ['class' => ['selected-entities-list']], |
71
|
|
|
'items' => array_map( |
72
|
|
|
function($id) use ($selected_entities, $details_id) { |
73
|
|
|
$entity = $selected_entities[$id]; |
74
|
|
|
return [ |
75
|
|
|
'#theme_wrappers' => ['container'], |
76
|
|
|
'#attributes' => [ |
77
|
|
|
'class' => ['selected-item-container'], |
78
|
|
|
'data-entity-id' => $entity->id() |
79
|
|
|
], |
80
|
|
|
'display' => ['#markup' => $entity->label()], |
81
|
|
|
'remove_button' => [ |
82
|
|
|
'#type' => 'submit', |
83
|
|
|
'#value' => $this->t('Remove'), |
84
|
|
|
'#ajax' => [ |
85
|
|
|
'callback' => [get_class($this), 'updateWidgetCallback'], |
86
|
|
|
'wrapper' => $details_id, |
87
|
|
|
], |
88
|
|
|
'#submit' => [[get_class($this), 'removeItemSubmit']], |
89
|
|
|
'#name' => 'remove_' . $id, |
90
|
|
|
'#attributes' => ['data-entity-id' => $id] |
91
|
|
|
], |
92
|
|
|
]; |
93
|
|
|
}, |
94
|
|
|
$ids |
95
|
|
|
), |
96
|
|
|
]; |
97
|
|
|
$form['use_selected'] = array( |
98
|
|
|
'#type' => 'submit', |
99
|
|
|
'#value' => t('Use selected'), |
100
|
|
|
'#name' => 'use_selected', |
101
|
|
|
); |
102
|
|
|
|
103
|
|
|
return $form; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Submit callback for remove buttons. |
108
|
|
|
*/ |
109
|
|
|
public static function removeItemSubmit(&$form, FormStateInterface $form_state) { |
110
|
|
|
$triggering_element = $form_state->getTriggeringElement(); |
111
|
|
|
if (!empty($triggering_element['#attributes']['data-entity-id'])) { |
112
|
|
|
$id = $triggering_element['#attributes']['data-entity-id']; |
113
|
|
|
$parents = array_slice($triggering_element['#parents'], 0, -4); |
114
|
|
|
$array_parents = array_slice($triggering_element['#array_parents'], 0, -4); |
115
|
|
|
|
116
|
|
|
// Find and remove correct entity. |
117
|
|
|
$values = explode(' ', $form_state->getValue(array_merge($parents, ['target_id']))); |
118
|
|
|
$values = array_filter( |
119
|
|
|
$values, |
120
|
|
|
function($item) use ($id) { return $item != $id; } |
121
|
|
|
); |
122
|
|
|
$values = implode(' ', $values); |
123
|
|
|
|
124
|
|
|
// Set new value for this widget. |
125
|
|
|
$target_id_element = &NestedArray::getValue($form, array_merge($array_parents, ['target_id'])); |
126
|
|
|
$form_state->setValueForElement($target_id_element, $values); |
127
|
|
|
NestedArray::setValue($form_state->getUserInput(), $target_id_element['#parents'], $values); |
128
|
|
|
|
129
|
|
|
// Rebuild form. |
130
|
|
|
$form_state->setRebuild(); |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* AJAX form callback. |
136
|
|
|
*/ |
137
|
|
View Code Duplication |
public static function updateWidgetCallback(array &$form, FormStateInterface $form_state) { |
|
|
|
|
138
|
|
|
$trigger = $form_state->getTriggeringElement(); |
139
|
|
|
// AJAX requests can be triggered by hidden "target_id" element when entities |
140
|
|
|
// are added or by one of the "Remove" buttons. Depending on that we need to |
141
|
|
|
// figure out where root of the widget is in the form structure and use this |
142
|
|
|
// information to return correct part of the form. |
143
|
|
|
if (!empty($trigger['#ajax']['event']) && $trigger['#ajax']['event'] == 'entity_browser_selected_updated') { |
144
|
|
|
$parents = array_slice($trigger['#array_parents'], 0, -2); |
145
|
|
|
} |
146
|
|
|
elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_remove_')) { |
147
|
|
|
$parents = array_slice($trigger['#array_parents'], 0, -4); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
return NestedArray::getValue($form, $parents); |
|
|
|
|
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* {@inheritdoc} |
155
|
|
|
*/ |
156
|
|
|
public function submit(array &$form, FormStateInterface $form_state) { |
157
|
|
|
if ($form_state->getTriggeringElement()['#name'] == 'use_selected') { |
158
|
|
|
$this->selectionDone($form_state); |
159
|
|
|
} |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
} |
163
|
|
|
|
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.