-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdynamic_entity_reference.module
129 lines (117 loc) · 5.32 KB
/
dynamic_entity_reference.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
/**
* @file
* Contains main module functionality.
*/
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\FieldConfigInterface;
/**
* Implements hook_entity_bundle_delete().
*
* We are duplicating the work done by
* \Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem::onDependencyRemoval()
* because we need to take into account bundles that are not provided by a
* config entity type so they are not part of the config dependencies.
*/
function dynamic_entity_reference_entity_bundle_delete($entity_type_id, $bundle) {
// Gather a list of all entity reference fields.
$map = Drupal::service('entity_field.manager')->getFieldMapByFieldType('dynamic_entity_reference');
$ids = [];
foreach ($map as $type => $info) {
foreach ($info as $name => $data) {
foreach ($data['bundles'] as $bundle_name) {
$ids[] = "$type.$bundle_name.$name";
}
}
}
// Update the 'target_bundles' handler setting if needed.
foreach (FieldConfig::loadMultiple($ids) as $field_config) {
$settings = $field_config->getSettings();
$target_types = DynamicEntityReferenceItem::getTargetTypes($settings);
if (in_array($entity_type_id, $target_types, TRUE) && isset($settings[$entity_type_id]['handler_settings'])) {
$handler_settings = $settings[$entity_type_id]['handler_settings'];
if (isset($handler_settings['target_bundles'][$bundle])) {
unset($handler_settings['target_bundles'][$bundle]);
$settings[$entity_type_id]['handler_settings'] = $handler_settings;
$field_config->setSettings($settings);
$field_config->save();
// In case we deleted the only target bundle allowed by the field we
// have to log a critical message because the field will not function
// correctly anymore.
if ($handler_settings['target_bundles'] === []) {
\Drupal::logger('dynamic_entity_reference')->critical('The %target_bundle bundle (entity type: %target_entity_type) was deleted. As a result, the %field_name dynamic entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', [
'%target_bundle' => $bundle,
'%target_entity_type' => $entity_type_id,
'%field_name' => $field_config->getName(),
'%entity_type' => $field_config->getTargetEntityTypeId(),
'%bundle' => $field_config->getTargetBundle(),
]);
}
}
}
}
}
/**
* Implements hook_ENTITY_TYPE_presave() for 'field_config'.
*
* @todo Clean this up once field_field_config_save is more accommodating.
*/
function dynamic_entity_reference_field_config_presave(FieldConfigInterface $field) {
// Don't change anything during a configuration sync.
if ($field->isSyncing()) {
return;
}
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
$er_item_class = EntityReferenceItem::class;
$class = $field_type_manager->getPluginClass($field->getType());
if ($class !== $er_item_class && !is_subclass_of($class, $er_item_class)) {
return;
}
$der_item_class = DynamicEntityReferenceItem::class;
if ($class === $der_item_class || is_subclass_of($class, $der_item_class)) {
// DER needs to be handled differently.
return;
}
// Just a normal ER item, do the things field_field_config_presave() would
// have done before we removed it in
// dynamic_entity_reference_module_implements_alter().
$selection_manager = \Drupal::service('plugin.manager.entity_reference_selection');
$target_type = $field->getFieldStorageDefinition()->getSetting('target_type');
[$current_handler] = explode(':', $field->getSetting('handler'), 2);
$field->setSetting('handler', $selection_manager->getPluginId($target_type, $current_handler));
}
/**
* Implements hook_module_implements_alter().
*/
function dynamic_entity_reference_module_implements_alter(&$implementations, $hook) {
if ($hook == 'field_config_presave') {
// We have to go after field_field_config_presave().
$group = $implementations['dynamic_entity_reference'];
unset($implementations['dynamic_entity_reference']);
// Remove the field implementation, we have a fallback in our hook.
unset($implementations['field']);
$implementations['dynamic_entity_reference'] = $group;
}
}
/**
* Implements hook_form_FORM_ID_alter() for 'field_ui_field_storage_add_form'.
*/
function dynamic_entity_reference_form_field_ui_field_storage_add_form_alter(array &$form) {
if (version_compare(\Drupal::VERSION, '10.1.999', '<')) {
$optgroup = (string) t('Dynamic entity reference');
// Move the "Dynamic entity reference" option to the end of the list and
// rename it to "Other".
unset($form['add']['new_storage_type']['#options'][$optgroup]['dynamic_entity_reference']);
$form['add']['new_storage_type']['#options'][$optgroup]['dynamic_entity_reference'] = t('Other…');
}
}
/**
* Implements hook_field_info_alter().
*/
function dynamic_entity_reference_field_info_alter(&$info) {
if (version_compare(\Drupal::VERSION, '10.1.999', '<')) {
$info['dynamic_entity_reference']['category'] = t('Dynamic Reference');
}
}