1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @file |
5
|
|
|
* Contains \Drupal\entity_browser\src\Element\EntityBrowserElement. |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Drupal\entity_browser\Element; |
9
|
|
|
|
10
|
|
|
use Drupal\Component\Utility\Html; |
11
|
|
|
use Drupal\Component\Utility\NestedArray; |
12
|
|
|
use Drupal\Core\Field\FieldStorageDefinitionInterface; |
13
|
|
|
use Drupal\Core\Form\FormStateInterface; |
14
|
|
|
use Drupal\Core\Render\Element\FormElement; |
15
|
|
|
use \Drupal\entity_browser\Entity\EntityBrowser; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Provides an Entity Browser render element. |
19
|
|
|
* |
20
|
|
|
* Configuration options are: |
21
|
|
|
* |
22
|
|
|
* @FormElement("entity_browser") |
23
|
|
|
*/ |
24
|
|
|
class EntityBrowserElement extends FormElement { |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* {@inheritdoc} |
28
|
|
|
*/ |
29
|
|
|
public function getInfo() { |
30
|
|
|
$class = get_class($this); |
31
|
|
|
return [ |
32
|
|
|
'#input' => TRUE, |
33
|
|
|
'#multiple' => FALSE, |
34
|
|
|
'#process' => [[$class, 'processEntityBrowser']], |
35
|
|
|
'#size' => 60, |
36
|
|
|
'#pre_render' => [[$class, 'preRenderEntityBrowser']], |
37
|
|
|
'#theme' => 'entity_browser', |
38
|
|
|
'#theme_wrappers' => ['form_element'], |
39
|
|
|
'#tree' => TRUE, |
40
|
|
|
'#attached' => [ |
41
|
|
|
'library' => ['entity_browser/entity_reference'] |
42
|
|
|
], |
43
|
|
|
]; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Processes the entity browser element. |
48
|
|
|
*/ |
49
|
|
|
public static function processEntityBrowser(&$element, FormStateInterface $form_state, &$complete_form) { |
50
|
|
|
/** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */ |
51
|
|
|
$entity_browser = EntityBrowser::load($element['#entity_browser_id']); |
52
|
|
|
|
53
|
|
|
$element['entity_browser'] = $entity_browser->getDisplay()->displayEntityBrowser(); |
54
|
|
|
|
55
|
|
|
if ($element['#cardinality'] == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || count($element['#default_value']) < $element['cardinality']) { |
56
|
|
|
$element['#attached']['drupalSettings']['entity_browser'] = [ |
57
|
|
|
'field_settings' => [ |
58
|
|
|
$entity_browser->getDisplay()->getUuid() => [ |
59
|
|
|
'cardinality' => $element['#cardinality'], |
60
|
|
|
], |
61
|
|
|
] |
62
|
|
|
]; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
return $element; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Prepares a #type 'entity_browser' render element for entity_browser.html.twig. |
70
|
|
|
* |
71
|
|
|
* @param array $element |
72
|
|
|
* An associative array containing the properties of the element. |
73
|
|
|
* |
74
|
|
|
* @return array |
75
|
|
|
* The $element with prepared variables ready for entity-browser.html.twig. |
76
|
|
|
*/ |
77
|
|
|
public static function preRenderEntityBrowser($element) { |
78
|
|
|
$hidden_id = Html::getUniqueId('edit-' . $element['#identifier'] . '-target-id'); |
79
|
|
|
$details_id = Html::getUniqueId('edit-' . $element['#identifier']); |
80
|
|
|
|
81
|
|
|
$element['#theme_wrappers'][] = [ |
82
|
|
|
'#id' => $details_id, |
83
|
|
|
'#type' => 'details', |
84
|
|
|
'#open' => !empty($ids), |
|
|
|
|
85
|
|
|
'target_id' => [ |
86
|
|
|
'#type' => 'hidden', |
87
|
|
|
'#id' => $hidden_id, |
88
|
|
|
// We need to repeat ID here as it is otherwise skipped when rendering. |
89
|
|
|
'#attributes' => ['id' => $hidden_id], |
90
|
|
|
'#default_value' => $element['#default_value'], |
91
|
|
|
// #ajax is officially not supported for hidden elements but if we |
92
|
|
|
// specify event manually it works. |
93
|
|
|
'#ajax' => [ |
94
|
|
|
'callback' => [self::class, 'updateWidgetCallback'], |
95
|
|
|
'wrapper' => $details_id, |
96
|
|
|
'event' => 'entity_browser_value_updated', |
97
|
|
|
], |
98
|
|
|
], |
99
|
|
|
]; |
100
|
|
|
|
101
|
|
|
$element['#variables']['entity_browser'] = $element['entity_browser']; |
102
|
|
|
|
103
|
|
|
return $element; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* {@inheritdoc} |
108
|
|
|
*/ |
109
|
|
|
public static function valueCallback(&$element, $input, FormStateInterface $form_state) { |
110
|
|
|
$return = []; |
111
|
|
|
return $return; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* AJAX form callback. |
116
|
|
|
*/ |
117
|
|
View Code Duplication |
public static function updateWidgetCallback(array &$form, FormStateInterface $form_state) { |
|
|
|
|
118
|
|
|
$trigger = $form_state->getTriggeringElement(); |
119
|
|
|
// AJAX requests can be triggered by hidden "target_id" element when entities |
120
|
|
|
// are added or by one of the "Remove" buttons. Depending on that we need to |
121
|
|
|
// figure out where root of the widget is in the form structure and use this |
122
|
|
|
// information to return correct part of the form. |
123
|
|
|
if (!empty($trigger['#ajax']['event']) && $trigger['#ajax']['event'] == 'entity_browser_value_updated') { |
124
|
|
|
$parents = array_slice($trigger['#array_parents'], 0, -2); |
125
|
|
|
} |
126
|
|
|
elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_remove_')) { |
127
|
|
|
$parents = array_slice($trigger['#array_parents'], 0, -4); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
return NestedArray::getValue($form, $parents); |
|
|
|
|
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
This check looks for calls to
isset(...)
orempty()
on variables that are yet undefined. These calls will always produce the same result and can be removed.This is most likely caused by the renaming of a variable or the removal of a function/method parameter.