Skip to content
Snippets Groups Projects

Base Node Map configuration form

3 files
+ 315
0
Compare changes
  • Side-by-side
  • Inline

Files

+ 295
0
<?php
namespace Drupal\entity_reference_map\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\FieldConfigInterface;
use Drupal\node\NodeTypeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Entity Reference map configuration form.
*/
class MapForm extends ConfigFormBase {
public const CONFIG_NAME = 'entity_references_map.config';
/**
* Drupal entity fields manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected EntityFieldManagerInterface $entityFieldManager;
/**
* Drupal entity type bundle info manager.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
protected EntityTypeBundleInfoInterface $entityTypeBundleInfoManager;
/**
* Constructs MapForm instance.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
EntityFieldManagerInterface $entityFieldManager,
EntityTypeBundleInfoInterface $entityTypeBundleInfoManager
) {
$this->configFactory = $config_factory;
$this->entityFieldManager = $entityFieldManager;
$this->entityTypeBundleInfoManager = $entityTypeBundleInfoManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('entity_field.manager'),
$container->get('entity_type.bundle.info')
);
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [self::CONFIG_NAME];
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'entity_reference_map.map_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, NodeTypeInterface $node_type = NULL) {
if (is_null($node_type)) {
$form['#markup'] = $this->t('Cannot find this node type.');
return $form;
}
$form_state->set('node_type', $node_type);
$form['#tree'] = TRUE;
$form['#attributes'] = [
'id' => 'map_form',
];
$form['enable_checkbox'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable Entity Reference Map for this node type'),
'#default_value' => 0,
'#attributes' => [
'id' => 'map_enable_checkbox',
],
];
$form['relationships'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'map_relationships_container',
],
'#states' => [
'visible' => [
':input[id="map_enable_checkbox"]' => ['checked' => TRUE],
],
],
];
$forward_reference_fields = $this->getForwardReferenceFieldsData('id_task');
$backward_reference_fields = $this->getBackwardReferenceFields('id_task');
$form_state->set('forward_reference_fields', $forward_reference_fields);
$form_state->set('backward_reference_fields', $backward_reference_fields);
$form['relationships']['description'] = [
'#markup' => $this->t('Please configure entity type relationships'),
];
$form['relationships']['forward_reference']['fields'] = $this->buildForwardReferenceCheckboxes($forward_reference_fields);
return parent::buildForm($form, $form_state);
}
/**
* Builds render array of form checkboxes for forward_reference fields.
*/
protected function buildForwardReferenceCheckboxes(array $forward_reference_fields) {
$build = [];
foreach ($forward_reference_fields as $field_id => $field_info) {
[
'label' => $field_label,
'multiple' => $is_multiple,
'machine_name' => $machine_name,
'referenced_entity_type' => $referenced_entity_type,
'referenced_entity_bundle' => $referenced_entity_bundle,
'referenced_entity_label' => $referenced_entity_label,
] = $field_info;
$build[$field_id] = [
Please register or sign in to reply
'#type' => 'checkbox',
'#title' => "{$referenced_entity_label}: {$field_label} ({$machine_name})" . ($is_multiple ? ' [multiple]' : ''),
'#default_value' => 0,
];
}
return $build;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->getUserInput();
$config = $this->config(self::CONFIG_NAME);
$node_type = $form_state->get('node_type');
$bundle_machine_name = $node_type->id();
if (empty($values['enable_checkbox'])) {
$config->clear($bundle_machine_name);
$config->save();
return;
}
foreach ($values['relationships'] as $relationship_type => $fields) {
$allowed_fields = array_keys(array_filter($fields['fields']));
$config->set("$bundle_machine_name.$relationship_type", $allowed_fields);
}
$config->set("$bundle_machine_name.type", $node_type->getEntityType()->getBundleOf());
$config->save();
parent::submitForm($form, $form_state);
}
/**
* Get "Entity reference" FieldConfigInterface items list of given node type.
*
* @param string $bundle
* Node bundle name.
* @param string $entity_type
* Entity type name.
*
* @return array
* Fields [field_config_id => FieldConfigInterface $item] associative array.
*/
public function getForwardReferenceFieldsList(string $bundle, string $entity_type = 'node'):array {
$fields = array_filter(
$this->entityFieldManager->getFieldDefinitions($entity_type, $bundle), function ($field_definition) {
return $field_definition instanceof FieldConfigInterface;
}
);
$transformedFields = [];
foreach ($fields as $key => &$field) {
/** @var \Drupal\field\Entity\FieldConfig $field */
if ($field->getType() !== 'entity_reference') {
continue;
}
$transformedFields[$field->id()] = $field;
}
return $transformedFields;
}
/**
* Get given entity bundle type "entity_reference" fields array data.
*
* @param string $bundle
* Entity bundle name.
* @param string $entity_type
* Entity type name.
*
* @return array
* [
* field_config_id => [
* 'label' => $item->label(),
* 'multiple' => $isMultiple,
* 'machine_name' => $item->getName(),
* 'referenced_entity_type' => $item->get('entity_type'),
* 'referenced_entity_bundle' => $item->get('bundle'),
* 'referenced_entity_label' => $label,
* ],
* ];
*/
public function getForwardReferenceFieldsData(string $bundle, string $entity_type = 'node'):array {
$entity_type_bundle_info_manager = $this->entityTypeBundleInfoManager;
return array_map(static function ($item) use ($entity_type_bundle_info_manager) {
/** @var \Drupal\field\Entity\FieldConfig $item */
return [
'label' => $item->label(),
'machine_name' => $item->getName(),
'multiple' => $item->getFieldStorageDefinition()->get('cardinality') !== 1,
'referenced_entity_type' => $item->get('entity_type'),
'referenced_entity_bundle' => $item->get('bundle'),
'referenced_entity_label' => $entity_type_bundle_info_manager->getBundleInfo($item->get('entity_type'))[$item->get('bundle')]['label'] ?? 'Underfined',
];
}, $this->getForwardReferenceFieldsList($bundle, $entity_type));
}
/**
* Get other nodes "entity_reference" fields that reference this node.
*
* @param string $bundle
* Entity bundle name.
* @param string $entity_type
* Entity type name.
*
* @return array
* $childEntitiesFields = [
* entity_type_id => [
* entity_bundle => [
* 'machine_name' => $field_machine_name,
* 'label' => $field_label,
* 'multiple' => $is_field_multiple,
* ]
* ]
* ]
*/
public function getBackwardReferenceFields(string $bundle, string $entity_type = 'node'):array {
$map = $this->entityFieldManager->getFieldMapByFieldType(
'entity_reference'
);
$ids = [];
foreach ($map as $type => $info) {
foreach ($info as $name => $data) {
foreach ($data['bundles'] as $bundle_name) {
$ids[] = "$type.$bundle_name.$name";
}
}
}
$filtered_map = [];
foreach (FieldConfig::loadMultiple($ids) as $field_config) {
$field_name = $field_config->getName();
$target_type = $field_config->getSetting('target_type');
if (!empty($target_type) && $target_type == $entity_type) {
$handler_settings = $field_config->getSetting('handler_settings');
if (isset($handler_settings['target_bundles'][$bundle])) {
$filtered_map[$entity_type][$field_config->get('bundle')] = [
'machine_name' => $field_name,
'label' => $field_config->getLabel(),
'multiple' => $field_config->getFieldStorageDefinition()->get('cardinality') !== 1,
];
}
}
}
return $filtered_map;
}
}
Loading