Repository URL to install this package:
|
Version:
2.1.0 ▾
|
<?php
namespace Drupal\dds\Commands;
use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\field\Entity\FieldConfig;
use Drush\Commands\DrushCommands;
use Drush\Exceptions\UserAbortException;
/**
* A Drush commandfile.
*
* In addition to this file, you need a drush.services.yml
* in root of your module, and a composer.json file that provides the name
* of the services file to use.
*
* See these files for an example of injecting Drupal services:
* - http://cgit.drupalcode.org/devel/tree/src/Commands/DevelCommands.php
* - http://cgit.drupalcode.org/devel/tree/drush.services.yml
*/
class DDSCommands extends DrushCommands {
/** @var \Drupal\Core\Entity\EntityFieldManager */
protected $entityFieldManager;
public function __construct(EntityFieldManager $entity_field_manager) {
parent::__construct();
$this->entityFieldManager = $entity_field_manager;
}
/**
* Rebuilds the bundle field maps inside the key value store.
*
* @param $type
* The entity type to rebuild field maps for.
* @param array $options
* An associative array of options whose values come from cli, aliases,
* config, etc.
* @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields|void
* @throws \Drush\Exceptions\UserAbortException
*
* @command rebuild:field-map
* @option force Force rebuilding even if no additions or removals were
* detected.
* @usage drush rebuild:field-map node --force
* Rebuild the field mappings for nodes and ignore if no changes were
* detected.
* @usage drush rebuild:field-map paragraph
* Rebuild the field mappings for paragraphs
* @aliases rfm,rebuild-field-map
* @table-style default
* @field-labels
* field: Field
* bundle: Bundle
* change: Change
*/
public function rebuildFieldMap($type, array $options = ['force' => FALSE, 'format' => 'table']) {
/** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $bundle_key_value */
$bundle_key_value = \Drupal::service('keyvalue')->get('entity.definitions.bundle_field_map');
$existing_mappings = $bundle_key_value->get($type);
$new_mappings = $this->getBundleMapByEntityType($type);
$added_mappings = array_diff_key($new_mappings, $existing_mappings);
$removed_mappings = array_diff_key($existing_mappings, $new_mappings);
$has_changes = !empty($added_mappings) || !empty($removed_mappings);
if ($has_changes) {
$this->output()->writeln(dt('Rebuilding stored field mapping values for @entity_type.', ['@entity_type' => $type]));
$rows = [];
// Add added mappings to the resulting rows.
foreach ($added_mappings as $field => $mappings) {
foreach ($mappings as $bundle) {
$rows[] = [
'field' => $field,
'bundle' => $bundle,
'change' => dt('Add')
];
}
}
// Add removed mappings to the resulting rows.
foreach ($removed_mappings as $field => $mappings) {
foreach ($mappings as $bundle) {
$rows[] = [
'field' => $field,
'bundle' => $bundle,
'change' => dt('Remove')
];
}
}
return new RowsOfFields($rows);
} else {
if ($options['force'] != TRUE) {
$this->output()->writeln(dt('There are no changes to be made. The stored field mappings matches the generated ones.'));
}
}
if ($has_changes || $options['force'] == TRUE) {
$bundle_key_value->set($type, $new_mappings);
drupal_flush_all_caches();
$this->output()->writeln(dt('The field mappings for @entity_type has been rebuilt.', ['@entity_type' => $type]));
}
}
/**
* Gets the field mappings for the given entity type.
*
* @param string $type
* The type of the entity to generate field mappings for.
*
* @return array
* An array of field mappings ready to store in the key value store.
*/
private function getBundleMapByEntityType($type) {
$bundle_field_map = [];
/** @var array $bundle_info */
$bundle_info = \Drupal::service('entity_type.bundle.info')->getBundleInfo($type);
foreach ($bundle_info as $bundle => $info) {
$definitions = $this->entityFieldManager->getFieldDefinitions($type, $bundle);
// If there are no definitions, we skip this loop and continue to the next.
if (empty($definitions)) {
continue;
}
// Filter out the definitions that are not of the target type.
$definitions = array_filter($definitions, function($definition) {
return $definition instanceof FieldConfig;
});
if (!empty($definitions)) {
foreach ($definitions as $field_definition) {
$field_bundle = $field_definition->getTargetBundle();
$field_name = $field_definition->getName();
if (!isset($bundle_field_map[$field_name])) {
// If the field doesn't exist yet we initialize it with type and empty bundle list.
$bundle_field_map[$field_name] = [
'type' => $field_definition->getType(),
'bundles' => []
];
}
$bundle_field_map[$field_name]['bundles'][$field_bundle] = $field_bundle;
}
}
}
return $bundle_field_map;
}
}