getStorage($entity_type); $entity_query = $entity_storage->getQuery(); if ($bundle) { $bundle_key = $entity_storage->getEntityType()->getKey('bundle'); $entity_query->condition($bundle_key, $bundle); } if ($field) { // Check that field BOTH is present on entity bundle AND has a value saved. $entity_query->exists($field); } $entity_query->accessCheck(FALSE); $entity_ids = $entity_query->execute(); return $entity_type_manager->getStorage($entity_type)->loadMultiple($entity_ids); } /** * Move (and optionally filter/transform) terms between term reference fields. */ function migration_helpers_move_terms( $destination_vocabulary, $source_field, $destination_field, $bundle = NULL, $entity_type = 'node', $mapping = [], ) { /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */ $entity_type_manager = \Drupal::service('entity_type.manager'); // Get any existing terms in destination vocabulary so we can efficiently // prevent duplication. $terms = migration_helpers_entity_query( entity_type: 'taxonomy_term', bundle: $destination_vocabulary, ); $term_data = []; foreach ($terms as $term) { $term_data[$term->id()] = $term->label(); } $nodes = migration_helpers_entity_query($entity_type, $bundle, $source_field); foreach ($nodes as $node) { $tids = []; /** @var \Drupal\node\NodeInterface $node */ $orig_values = $node->get($source_field); foreach ($orig_values as $orig_value) { $orig_tid = $orig_value->target_id; $orig_term = $entity_type_manager->getStorage('taxonomy_term')->load($orig_tid); $orig = $orig_term->name->value; $term_name = $mapping[$orig] ?? $orig; // If our map intentionally blanked out the term name, do not create // a term in the new vocabulary and assign it to the destination field. // Note, the term must be blanked out ('') or assigned to FALSE in the // mapping, setting a term to NULL is the same as not mapping it, and it // would be created in the new vocab etc. if (!$term_name) { continue; } $tid = array_search($term_name, $term_data); if (empty($tid)) { $new_term = $entity_type_manager->getStorage('taxonomy_term')->create([ 'name' => $term_name, 'vid' => $destination_vocabulary, ]); $new_term->save(); $tid = $new_term->id(); \Drupal::logger('mass')->log(LogLevel::INFO, "Term $term_name created with TID $tid in vocabulary $destination_vocabulary."); // Because we did the query only once, before we entered this loop, we // need to add our newly created terms to the term data array we use to // check for existing terms… or we'll keep creating duplicates. $term_data[$new_term->id()] = $new_term->label(); } $tids[] = $tid; } // Now we have collected all the term IDs that have been created. // We have to go through a surprising number of hoops to make our $already_there_tids = []; $already_there_values = $node->get($destination_field); foreach ($already_there_values as $already_there_value) { $already_there_tids[] = $already_there_value->target_id; } $node->set($destination_field, array_merge($tids, $already_there_tids)); $node->save(); } } // The below almost serve more as examples that can be followed function migration_helpers_text_list_to_boolean($old_field_name, $new_field_name, $bundle, $entity_type = 'node', $value_map = NULL) { $value_map = $value_map ?? [ 'Yes' => TRUE, 'No' => FALSE, ]; $nodes = migration_helpers_entity_query($entity_type, $bundle, $old_field_name); foreach ($nodes as $node) { /** @var \Drupal\node\NodeInterface $node */ $orig_value = trim($node->$old_field_name->value); $new_value = $value_map[$orig_value] ?? (boolean) $orig_value; $node->set($new_field_name, $new_value); $node->save(); } }