The core migrate lookup process plugin always returns an entity ID.

However, references from config entities that point to content entities use UUIDs. For example, a Commerce condition on the store entity.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joachim created an issue. See original summary.

joachim’s picture

Status: Needs review » Needs work
heddn’s picture

Closing #2926200: Add process plugin for loading values from existing entities as duplicate to here..

  1. +++ b/src/Plugin/migrate/process/EntityValue.php
    @@ -0,0 +1,113 @@
    + *     field_property: uri
    

    Can we remove this option and just return the whole field? If we need to cherry-pick specific values, we can use extract process plugin.

  2. +++ b/src/Plugin/migrate/process/EntityValue.php
    @@ -0,0 +1,113 @@
    +    if (empty($this->configuration['entity_type'])) {
    +      throw new MigrateException("'entity_type' configuration must be specified for migrate_plus_entity_value process plugin.");
    +    }
    +    if (empty($this->configuration['field_name'])) {
    +      throw new MigrateException("'field_name' configuration must be specified for migrate_plus_entity_value process plugin.");
    +    }
    

    Can we move all this to the constructor and return a BadPluginDefinitionException instead of migration exception?

  3. +++ b/src/Plugin/migrate/process/EntityValue.php
    @@ -0,0 +1,113 @@
    +    $entity_type = $this->configuration['entity_type'];
    +
    +    $entity = $this->entityTypeManager->getStorage($entity_type)->load($value);
    +
    +    if (empty($entity)) {
    +      throw new MigrateException("Unable to load an {$entity_type} entity with ID {$value} in migrate_plus_entity_value process plugin.");
    

    And check the entity type is a valid entity type in the constructor and return an InvalidArgumentException if it isn't? This also in constructor.

  4. +++ b/src/Plugin/migrate/process/EntityValue.php
    @@ -0,0 +1,113 @@
    +    try {
    +      $field_value = $entity->get($this->configuration['field_name'])->{$field_property};
    ...
    +    catch (\Exception $e) {
    +      // Re-throw any exception thrown by the entity system.
    +      throw new MigrateException("Got exception reading field value {$this->configuration['field_name']} on 'entity_type' {$entity_type} entity with ID {$value} in migrate_plus_entity_value process plugin:" . $e->getMessage());
    

    I like this! I forgot to ask for that in the other issue. This is great.

heddn’s picture

Issue tags: +Needs tests

Also, needs tests.

esolitos’s picture

Should this maybe be based on the entity lookup plugin? I mean, the difference could be very small and we could share most of the code I believe.

joachim’s picture

I think they’re best kept separate.
The entity lookup plugin has variable input parameters, and a simple output.
This entity value plugin has a simple input, and variable output.

Combining them seems like it will increase complexity and make testing and usage harder.

It’s simple to chain them together.

geek-merlin’s picture

Following the unix phliosophy of doing just one thing well, i'd propose that related issue.

geek-merlin’s picture

Much improved work in the other issue.

maks9889’s picture

I have updated the patch with code from "#3018849: Add a LoadEntity process plugin" but with loading concrete field.

maks9889’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

tests are now in the patch

geek-merlin’s picture

I'm actively working with the patch from the other issue and think it obsoletes this one.

oldspot’s picture

Status: Needs review » Reviewed & tested by the community

I can see the other issue has the status "Closed (won't fix)" now so I've used the patch in this issue. I can confirm I can extract the field value correctly from the loaded entity.
In my case I combined it with a 'migration_lookup' plugin where I had to extract the 'fid' (file id) of a previously migrated Media entity and worked great:

  field_avatar:
    - plugin: migration_lookup
      source: picture
      migration: images_to_media
      no_stub: true
    - plugin: entity_value
      entity_type: media
      field_name: field_media_image
joachim’s picture

This works nicely with the entity_lookup plugin too.

I have a migration where I am creating new Media entities based on an image field on a content entity (and a subsequent migration will populate a new media reference field to point to the new Media entity).

To set the name field on the new Media entities, I am doing this:

  name:
    # Get the name for the media from the referenced file's filename.
    -
      # The destination data for field_media_image is an entity reference field
      # array, so extract just the target entity ID.
      plugin: extract
      source: '@field_media_image'
      index:
        - target_id
    -
      # Find the file entity.
      plugin: entity_lookup
      entity_type: file
      value_key: fid
      access_check: false
    -
      # Extract the filename.
      plugin: entity_value
      entity_type: file
      field_name: filename
Eduardo Morales Alberti’s picture

Really helpful, that's what I needed.

  • heddn committed ee0e4e0 on 8.x-5.x authored by maks9889
    Issue #2974221 by joachim, maks9889, heddn: add a process plugin for...
heddn’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for your contributions.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

marvil07’s picture

Thanks to all people involved here!

For reference, I closed a related gitlab issue #262: Retrieve a field from an existing entity, with a similar plugin.