1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Drupal\entity_browser\Element; |
4
|
|
|
|
5
|
|
|
use Drupal\Component\Utility\Html; |
6
|
|
|
use Drupal\Core\Form\FormStateInterface; |
7
|
|
|
use Drupal\Core\Render\Element\FormElement; |
8
|
|
|
use Drupal\entity_browser\Entity\EntityBrowser; |
9
|
|
|
use Drupal\Core\Entity\EntityInterface; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Provides an Entity Browser form element. |
13
|
|
|
* |
14
|
|
|
* Properties: |
15
|
|
|
* - #entity_browser: Entity browser or ID of the Entity browser to be used. |
16
|
|
|
* - #cardinality: (optional) Maximum number of items that are expected from |
17
|
|
|
* the entity browser. Unlimited by default. |
18
|
|
|
* - #default_value: (optional) Array of entities that Entity browser should be |
19
|
|
|
* initialized with. |
20
|
|
|
* - #entity_browser_validators: (optional) Array of validators that are to be |
21
|
|
|
* passed to the entity browser. Array keys are plugin IDs and array values |
22
|
|
|
* are plugin configuration values. Cardinality validator will be set |
23
|
|
|
* automatically. |
24
|
|
|
* |
25
|
|
|
* Return value will be an array of selected entities, which will appear under |
26
|
|
|
* 'entities' key on the root level of the element's values in the form state. |
27
|
|
|
* |
28
|
|
|
* @FormElement("entity_browser") |
29
|
|
|
*/ |
30
|
|
|
class EntityBrowserElement extends FormElement { |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Indicating an entity browser can return an unlimited number of values. |
34
|
|
|
*/ |
35
|
|
|
const CARDINALITY_UNLIMITED = -1; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* {@inheritdoc} |
39
|
|
|
*/ |
40
|
|
|
public function getInfo() { |
41
|
|
|
$class = get_class($this); |
42
|
|
|
return [ |
43
|
|
|
'#input' => TRUE, |
44
|
|
|
'#tree' => TRUE, |
45
|
|
|
'#cardinality' => $this::CARDINALITY_UNLIMITED, |
46
|
|
|
'#process' => [[$class, 'processEntityBrowser']], |
47
|
|
|
'#default_value' => [], |
48
|
|
|
'#entity_browser_validators' => [], |
49
|
|
|
'#attached' => ['library' => ['entity_browser/common']], |
50
|
|
|
]; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Render API callback: Processes the entity browser element. |
55
|
|
|
*/ |
56
|
|
|
public static function processEntityBrowser(&$element, FormStateInterface $form_state, &$complete_form) { |
57
|
|
|
/** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */ |
58
|
|
|
if (is_string($element['#entity_browser'])) { |
59
|
|
|
$entity_browser = EntityBrowser::load($element['#entity_browser']); |
60
|
|
|
} |
61
|
|
|
else { |
62
|
|
|
$entity_browser = $element['#entity_browser']; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
$default_value = implode(' ', array_map( |
66
|
|
|
function (EntityInterface $item) { |
67
|
|
|
return $item->getEntityTypeId() . ':' . $item->id(); |
68
|
|
|
}, |
69
|
|
|
$element['#default_value'] |
70
|
|
|
)); |
71
|
|
|
$validators = array_merge( |
72
|
|
|
$element['#entity_browser_validators'], |
73
|
|
|
['cardinality' => ['cardinality' => $element['#cardinality']]] |
74
|
|
|
); |
75
|
|
|
|
76
|
|
|
$display = $entity_browser->getDisplay(); |
77
|
|
|
$display->setUuid(sha1(implode('-', array_merge([$complete_form['#build_id']], $element['#parents'])))); |
78
|
|
|
$element['entity_browser'] = [ |
79
|
|
|
'#eb_parents' => array_merge($element['#parents'], ['entity_browser']), |
80
|
|
|
]; |
81
|
|
|
$element['entity_browser'] = $display->displayEntityBrowser( |
82
|
|
|
$element['entity_browser'], |
83
|
|
|
$form_state, |
84
|
|
|
$complete_form, |
85
|
|
|
['validators' => $validators, 'selected_entities' => $element['#default_value']] |
86
|
|
|
); |
87
|
|
|
|
88
|
|
|
$hidden_id = Html::getUniqueId($element['#id'] . '-target'); |
89
|
|
|
$element['entity_ids'] = [ |
90
|
|
|
'#type' => 'hidden', |
91
|
|
|
'#id' => $hidden_id, |
92
|
|
|
// We need to repeat ID here as it is otherwise skipped when rendering. |
93
|
|
|
'#attributes' => ['id' => $hidden_id, 'class' => ['ed-target']], |
94
|
|
|
'#default_value' => $default_value, |
95
|
|
|
]; |
96
|
|
|
|
97
|
|
|
$element['#attached']['drupalSettings']['entity_browser'] = [ |
98
|
|
|
$entity_browser->getDisplay()->getUuid() => [ |
99
|
|
|
'cardinality' => $element['#cardinality'], |
100
|
|
|
'selector' => '#' . $hidden_id, |
101
|
|
|
], |
102
|
|
|
]; |
103
|
|
|
|
104
|
|
|
return $element; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* {@inheritdoc} |
109
|
|
|
*/ |
110
|
|
|
public static function valueCallback(&$element, $input, FormStateInterface $form_state) { |
111
|
|
|
if ($input === FALSE) { |
112
|
|
|
return $element['#default_value'] ?: []; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
$entities = []; |
116
|
|
|
if ($input['entity_ids']) { |
117
|
|
|
$entities = static::processEntityIds($input['entity_ids']); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
return ['entities' => $entities]; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Processes entity IDs and gets array of loaded entities. |
125
|
|
|
* |
126
|
|
|
* @param array|string $ids |
127
|
|
|
* Processes entity IDs as they are returned from the entity browser. They |
128
|
|
|
* are in [entity_type_id]:[entity_id] form. Array of IDs or a |
129
|
|
|
* space-delimited string is supported. |
130
|
|
|
* |
131
|
|
|
* @return \Drupal\Core\Entity\EntityInterface[] |
132
|
|
|
* Array of entity objects. |
133
|
|
|
*/ |
134
|
|
|
public static function processEntityIds($ids) { |
135
|
|
|
if (!is_array($ids)) { |
136
|
|
|
$ids = array_filter(explode(' ', $ids)); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
return array_map( |
140
|
|
|
function ($item) { |
141
|
|
|
list($entity_type, $entity_id) = explode(':', $item); |
142
|
|
|
return \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity_id); |
143
|
|
|
}, |
144
|
|
|
$ids |
145
|
|
|
); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Processes entity IDs and gets array of loaded entities. |
150
|
|
|
* |
151
|
|
|
* @param string $id |
152
|
|
|
* Processes entity ID as it is returned from the entity browser. ID should |
153
|
|
|
* be in [entity_type_id]:[entity_id] form. |
154
|
|
|
* |
155
|
|
|
* @return \Drupal\Core\Entity\EntityInterface |
156
|
|
|
* Entity object. |
157
|
|
|
*/ |
158
|
|
|
public static function processEntityId($id) { |
159
|
|
|
$return = static::processEntityIds([$id]); |
160
|
|
|
return current($return); |
|
|
|
|
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
} |
164
|
|
|
|