field_inheritance.module in Field Inheritance 8
Same filename and directory in other branches
Contains field_inheritance.module.
File
field_inheritance.moduleView source
<?php
/**
* @file
* Contains field_inheritance.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\field_inheritance\FieldStorageDefinition;
use Drupal\field\Entity\FieldConfig;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Url;
use Drupal\Component\Serialization\Json;
/**
* Implements hook_help().
*/
function field_inheritance_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the field_inheritance module.
case 'help.page.field_inheritance':
$output = '';
return $output;
default:
}
}
/**
* Implements hook_entity_bundle_field_info_alter().
*/
function field_inheritance_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
// Grab inherited fields just for the current entity type and bundle.
$inherited_field_ids = \Drupal::entityQuery('field_inheritance')
->condition('destinationEntityType', $entity_type
->id())
->condition('destinationEntityBundle', $bundle)
->execute();
if (!empty($inherited_field_ids)) {
$inherited_fields = \Drupal::entityTypeManager()
->getStorage('field_inheritance')
->loadMultiple($inherited_field_ids);
if (!empty($inherited_fields)) {
$x = 0;
foreach ($inherited_fields as $field) {
// We are only interested in adding computed fields to the destination
// entity type.
if ($field
->destinationEntityType() !== $entity_type
->id()) {
continue;
}
// We are only interested in adding computed fields to the destination
// entity bundle.
if ($field
->destinationEntityBundle() !== $bundle) {
continue;
}
// Configure the settings array with all the values from the config
// entity.
$settings = [
'id' => $field
->idWithoutTypeAndBundle(),
'source entity type' => $field
->sourceEntityType(),
'source entity bundle' => $field
->sourceEntityBundle(),
'source field' => $field
->sourceField(),
'method' => $field
->type(),
'plugin' => $field
->plugin(),
];
// Only set the destination field if one was configured, which will be
// for inheritance strategies other than inherit.
if ($field
->destinationField()) {
$settings['destination field'] = $field
->destinationField();
}
// Grab the configuration of the source field.
$source_field = FieldConfig::loadByName($field
->sourceEntityType(), $field
->sourceEntityBundle(), $field
->sourceField());
if (!empty($source_field)) {
$settings = array_merge($settings, $source_field
->getSettings());
$type = $source_field
->getType();
}
else {
// This may be a basefield.
$basefields = \Drupal::service('entity_field.manager')
->getBaseFieldDefinitions($field
->sourceEntityType());
if (!empty($basefields[$field
->sourceField()])) {
$source_field = $basefields[$field
->sourceField()];
$settings = array_merge($settings, $source_field
->getSettings());
$type = $source_field
->getType();
}
else {
continue;
}
}
// Set the factory class used to inherit the data from the source.
$class = '\\Drupal\\field_inheritance\\FieldInheritanceFactory';
if ($field
->plugin() === 'entity_reference_inheritance') {
$class = '\\Drupal\\field_inheritance\\EntityReferenceFieldInheritanceFactory';
}
// Allow developers to override the class to use for a field.
\Drupal::moduleHandler()
->alter('field_inheritance_inheritance_class', $class, $field);
// Add a computed field for the inherited field to the appropriate
// destination entity type and bundle.
$fields[$field
->idWithoutTypeAndBundle()] = FieldStorageDefinition::create($type)
->setLabel(t('@label', [
'@label' => $field
->label(),
]))
->setName($field
->idWithoutTypeAndBundle())
->setDescription(t('The inherited field: @field', [
'@field' => $field
->label(),
]))
->setComputed(TRUE)
->setClass($class)
->setSettings($settings)
->setTargetEntityTypeId($field
->destinationEntityType())
->setTargetBundle($field
->destinationEntityBundle())
->setTranslatable(FALSE)
->setRevisionable(FALSE)
->setReadOnly(TRUE)
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
'weight' => 50 + $x,
]);
$x++;
}
}
}
}
/**
* Implements hook_form_alter().
*/
function field_inheritance_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form_object = $form_state
->getFormObject();
if (!empty($form_object) && $form_object instanceof EntityForm) {
$entity = $form_state
->getFormObject()
->getEntity();
if (!empty($entity) && $entity instanceof FieldableEntityInterface && strpos($form['#id'], 'delete') === FALSE) {
$entity_type = $entity
->getEntityTypeId();
$bundle = $entity
->bundle();
$config = \Drupal::config('field_inheritance.config');
$included_entities = $config
->get('included_entities');
$included_bundles = $config
->get('included_bundles');
if (!empty($included_entities)) {
$included_entities = explode(',', $included_entities);
if (array_search($entity_type, $included_entities) === FALSE) {
return;
}
}
if (!empty($included_bundles)) {
$included_bundles = explode(',', $included_bundles);
if (array_search($entity_type . ':' . $bundle, $included_bundles) === FALSE) {
return;
}
}
$state_key = $entity
->getEntityTypeId() . ':' . $entity
->uuid();
$state = \Drupal::keyValue('field_inheritance');
$state_values = $state
->get($state_key);
$form['actions']['submit']['#submit'][] = 'field_inheritance_entity_form_submit';
$form['#attached']['library'][] = 'core/drupal.dialog.ajax';
$form['field_inheritance'] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => t('Field Inheritance'),
'#attributes' => [
'id' => 'field-inheritance--wrapper',
],
];
$form['field_inheritance']['field_inheritance_enable'] = [
'#type' => 'checkbox',
'#title' => t('Enable inheritance for this entity?'),
'#description' => t('Enabling inheritance will allow data to be pulled in from a source entity into this entity.'),
'#default_value' => $state_values['enabled'] ?? NULL,
];
$form['field_inheritance']['fields'] = [
'#type' => 'fieldset',
'#title' => t('Field Mappings'),
'#states' => [
'visible' => [
'input[name="field_inheritance_enable"]' => [
'checked' => TRUE,
],
],
],
];
$inherited_field_ids = \Drupal::entityQuery('field_inheritance')
->condition('destinationEntityType', $entity_type)
->condition('destinationEntityBundle', $bundle)
->execute();
if (!empty($inherited_field_ids)) {
$inherited_fields = \Drupal::entityTypeManager()
->getStorage('field_inheritance')
->loadMultiple($inherited_field_ids);
if (!empty($inherited_fields)) {
foreach ($inherited_fields as $field) {
$form['field_inheritance']['fields']['field_inheritance_' . $field
->idWithoutTypeAndBundle()] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => t('Entity Mapping for @label [@entity: @bundle - @field]', [
'@label' => $field
->label(),
'@entity' => $field
->sourceEntityType(),
'@bundle' => $field
->sourceEntityBundle(),
'@field' => $field
->sourceField(),
]),
'field_inheritance_field_skip_' . $field
->idWithoutTypeAndBundle() => [
'#type' => 'checkbox',
'#title' => t('Do not inherit this field'),
'#description' => t('Checking this box will prevent data from being inherited for this field on this entity.'),
'#default_value' => $state_values[$field
->idWithoutTypeAndBundle()]['skip'] ?? FALSE,
],
'field_inheritance_field_entity_' . $field
->idWithoutTypeAndBundle() => [
'#type' => 'entity_autocomplete',
'#title' => t('Source Entity'),
'#description' => t('Enter the name of the %bundle from which to inherit data.', [
'%bundle' => $field
->sourceEntityBundle(),
]),
'#target_type' => $field
->sourceEntityType(),
'#selection_settings' => [
'target_bundles' => [
$field
->sourceEntityBundle(),
],
],
'#default_value' => !empty($state_values[$field
->idWithoutTypeAndBundle()]['entity']) ? \Drupal::entityTypeManager()
->getStorage($field
->sourceEntityType())
->load($state_values[$field
->idWithoutTypeAndBundle()]['entity']) : FALSE,
'#states' => [
'invisible' => [
'input[name="field_inheritance_field_skip_' . $field
->idWithoutTypeAndBundle() . '"]' => [
'checked' => TRUE,
],
],
],
],
];
}
}
}
$form['field_inheritance']['fields']['message'] = [
'#type' => 'markup',
'#markup' => '<div id="field-inheritance-ajax-message"></div>',
];
$form['field_inheritance']['fields']['ajax_container'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'field-inheritance-ajax-container',
],
];
$form['field_inheritance']['fields']['add'] = [
'#type' => 'fieldset',
'#access' => \Drupal::currentUser()
->hasPermission('administer field inheritance'),
'message' => [
'#type' => 'markup',
'#prefix' => '<p>',
'#markup' => t('Add a new field inheritance field to this entity type and bundle.'),
'#suffix' => '</p>',
],
'add_field_inheritance' => [
'#type' => 'link',
'#title' => t('Add Field Inheritance'),
'#url' => Url::fromRoute('field_inheritance.creation_form', [
'entity_type' => $entity
->getEntityTypeId(),
'entity_bundle' => $entity
->bundle(),
]),
'#attributes' => [
'class' => [
'use-ajax',
'button',
'button--small',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => '60%',
]),
],
],
];
}
}
}
/**
* Form Submit Callback: Field Inheritance Entity Form.
*/
function field_inheritance_entity_form_submit(&$form, FormStateInterface $form_state) {
$state = \Drupal::keyValue('field_inheritance');
$entity = $form_state
->getFormObject()
->getEntity();
$values = $form_state
->getValues();
$state_key = $entity
->getEntityTypeId() . ':' . $entity
->uuid();
$state_value = [];
if (!empty($values['field_inheritance_enable'])) {
$state_value['enabled'] = TRUE;
foreach ($values as $value_name => $value) {
if (strpos($value_name, 'field_inheritance_field_') === 0) {
$inheritance_name = preg_replace('/^field_inheritance_field_(skip|entity)_/', '', $value_name);
if (!empty($values['field_inheritance_field_skip_' . $inheritance_name])) {
$state_value[$inheritance_name]['skip'] = TRUE;
}
elseif (!empty($values['field_inheritance_field_entity_' . $inheritance_name])) {
$state_value[$inheritance_name]['entity'] = $value;
}
}
}
}
else {
$state_value['enabled'] = FALSE;
}
if (!empty($state_value)) {
$state
->set($state_key, $state_value);
}
else {
$state
->delete($state_key);
}
}
/**
* AJAX Form Callback: Field Inheritance Entity Form.
*/
function field_inheritance_entity_form_add(&$form, FormStateInterface $form_state) {
$entity = $form_state
->getFormObject()
->getEntity();
$inheritance_entity = \Drupal::entityTypeManager()
->getStorage('field_inheritance')
->create();
$inheritance_entity
->setDestinationEntityType($entity
->getEntityTypeId());
$inheritance_entity
->setDestinationEntityBundle($entity
->bundle());
$response = new AjaxResponse();
$modal_form = \Drupal::service('entity.form_builder')
->getForm($inheritance_entity, 'add');
$response
->addCommand(new OpenModalDialogCommand('Add Field Inheritance', $modal_form, [
'width' => '800',
]));
return $response;
}
Functions
Name | Description |
---|---|
field_inheritance_entity_bundle_field_info_alter | Implements hook_entity_bundle_field_info_alter(). |
field_inheritance_entity_form_add | AJAX Form Callback: Field Inheritance Entity Form. |
field_inheritance_entity_form_submit | Form Submit Callback: Field Inheritance Entity Form. |
field_inheritance_form_alter | Implements hook_form_alter(). |
field_inheritance_help | Implements hook_help(). |