5 * Hook implementations for entity_browser_entity_form.module.
7 * Provides integration with the Inline entity form module.
10 use Drupal\Core\Form\FormStateInterface;
11 use Drupal\Core\Field\FieldDefinitionInterface;
12 use Drupal\Core\Field\WidgetInterface;
14 use Drupal\Component\Utility\NestedArray;
15 use Drupal\entity_browser\Element\EntityBrowserElement;
16 use Drupal\Core\Field\FieldStorageDefinitionInterface;
19 * Implements hook_inline_entity_form_reference_form_alter().
21 function entity_browser_entity_form_inline_entity_form_reference_form_alter(&$reference_form, FormStateInterface &$form_state) {
22 /** @var \Drupal\field\FieldConfigInterface $instance */
23 $instance = $form_state->get([
25 $reference_form['#ief_id'],
29 /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
30 $entity_form_id = $instance->getTargetEntityTypeId() . '.' . $instance->getTargetBundle() . '.default';
31 // TODO - 'default' might become configurable or something else in the future.
32 // See https://www.drupal.org/node/2510274
33 $form_display = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load($entity_form_id);
35 $widget = $form_display->getRenderer($instance->getName());
37 $entity_browser_id = $widget->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id', '_none');
38 if ($entity_browser_id === '_none') {
42 // Fetch the number of currently selected entities, if any.
43 $count_existing_selection = count($form_state->get([
45 $reference_form['#ief_id'],
49 $cardinality = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED;
50 if($instance->getFieldStorageDefinition()->get('cardinality') !== $cardinality) {
51 $cardinality = $instance->getFieldStorageDefinition()->get('cardinality') - $count_existing_selection;
54 unset($reference_form['entity_id']);
55 $reference_form['entity_browser'] = [
56 '#type' => 'entity_browser',
57 '#entity_browser' => $entity_browser_id,
58 '#cardinality' => $cardinality,
60 $reference_form['#attached']['library'][] = 'entity_browser_entity_form/ief_autocomplete';
61 $reference_form['actions']['ief_reference_save']['#ajax']['event'] = 'entities-selected';
63 // Add custom validation and submit callbacks as we need to handle
65 $reference_form['#element_validate'][0] = 'entity_browser_entity_form_reference_form_validate';
66 $reference_form['#ief_element_submit'][0] = 'entity_browser_entity_form_reference_form_submit';
70 * Validates the form for adding existing entities.
72 * TODO see if we can get away without overriding entire IEF function.
74 * @param array $reference_form
75 * The reference entity form.
76 * @param \Drupal\Core\Form\FormStateInterface $form_state
77 * The form state of the parent form.
79 * @see inline_entity_form_reference_form_validate()
81 function entity_browser_entity_form_reference_form_validate(array &$reference_form, FormStateInterface $form_state) {
82 $form_values = NestedArray::getValue($form_state->getValues(), $reference_form['#parents']);
83 if (empty($form_values['entity_browser']['entity_ids'])) {
84 // The entity_id element is required, the value is empty only if
85 // the form was cancelled.
88 $ief_id = $reference_form['#ief_id'];
89 $labels = $reference_form['#ief_labels'];
90 $attach_entities = EntityBrowserElement::processEntityIds($form_values['entity_browser']['entity_ids']);
92 // Check if the entity is already referenced by the field.
93 if (!empty($attach_entities)) {
94 foreach ($attach_entities as $attach_entity) {
95 foreach ($form_state->get(['inline_entity_form', $ief_id, 'entities']) as $key => $value) {
96 if ($value['entity'] == $attach_entity) {
97 $form_state->setError($reference_form, t('The selected @label has already been added.', ['@label' => $labels['singular']]));
105 * Submits the form for adding existing entities.
107 * Adds the specified entity to the IEF form state.
109 * TODO see if we can get away without overriding entire IEF function.
111 * @param array $reference_form
112 * The reference entity form.
113 * @param \Drupal\Core\Form\FormStateInterface $form_state
114 * The form state of the parent form.
116 * @see inline_entity_form_reference_form_submit()
118 function entity_browser_entity_form_reference_form_submit($reference_form, FormStateInterface $form_state) {
119 $ief_id = $reference_form['#ief_id'];
120 $form_values = NestedArray::getValue($form_state->getValues(), $reference_form['#parents']);
121 $attach_entities = EntityBrowserElement::processEntityIds($form_values['entity_browser']['entity_ids']);
122 $entities =& $form_state->get(['inline_entity_form', $ief_id, 'entities']);
124 // Determine the correct weight of the new element.
127 $weight = max(array_keys($entities)) + 1;
130 foreach ($attach_entities as $attach_entity) {
132 'entity' => $attach_entity,
135 'needs_save' => FALSE,
139 $form_state->set(['inline_entity_form', $ief_id, 'entities'], $entities);
141 // In some rare cases entity_ids keeps values of selected entities which then
142 // causes problems in subsequent selections. Let's make sure it is empty and
143 // ready for next usage of entity browser.
144 $form_state->setValueForElement($reference_form['entity_browser']['entity_ids'], '');
145 $input = &$form_state->getUserInput();
146 NestedArray::unsetValue($input, array_merge($reference_form['#parents'], ['entity_browser', 'entity_ids']));
150 * Implements hook_field_widget_third_party_settings_form().
152 function entity_browser_entity_form_field_widget_third_party_settings_form(WidgetInterface $plugin, FieldDefinitionInterface $field_definition, $form_mode, $form, FormStateInterface $form_state) {
153 if ($plugin->getPluginId() == 'inline_entity_form_complex') {
154 $entity_browsers = \Drupal::service('entity_type.manager')->getStorage('entity_browser')->loadMultiple();
155 if ($entity_browsers) {
157 foreach ($entity_browsers as $entity_browser) {
158 $options[$entity_browser->id()] = $entity_browser->label();
160 $element['entity_browser_id'] = [
162 '#title' => t('Entity browser'),
163 '#options' => $options,
164 '#empty_option' => t('- None -'),
165 '#empty_value' => '_none',
166 '#default_value' => $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id'),
170 $element['message'] = [
171 '#markup' => t('There are no entity browsers available. You can create one <a href="@url">here</a>.', ['@url' => Url::fromRoute('entity.entity_browser.collection')->toString()]),
179 * Implements hook_field_widget_settings_summary_alter().
181 function entity_browser_entity_form_field_widget_settings_summary_alter(&$summary, $context) {
182 $plugin = $context['widget'];
183 if ($plugin->getPluginId() == 'inline_entity_form_complex' && $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id') && $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id') !== '_none') {
184 $entity_browser_id = $plugin->getThirdPartySetting('entity_browser_entity_form', 'entity_browser_id');
185 $entity_browser = \Drupal::service('entity_type.manager')->getStorage('entity_browser')->load($entity_browser_id);
186 if ($entity_browser) {
187 $summary[] = t('Entity browser: @entity_browser.', [
188 '@entity_browser' => $entity_browser->label(),