Score:0

Migrating an array of values into multiple entities

ph flag

I'm using migrate/migrate_plus modules to import CSV files and generate entities.

One of the columns in the CSV can contain multiple values like 1|2|3, which I'm converting to an array using:

_jurisdictions:
  plugin: explode
  source: jurisdiction
  delimiter: "|"

I'm then using the array to generate taxonomy terms with this:

field_political_district:
  -
    plugin: entity_generate
    source: "@_jurisdictions"
    entity_type: taxonomy_term
    bundle: political_district
    bundle_key: vid
    value_key: name
    ignore_case: true
    values:
      field_display_name: ???

I'm stuck on two things:

  • I want to append a constant value to each name so that the taxonomy term name becomes "1, XYZ" where XYZ comes from constants/ABC
  • I want field_display_name to be the the value prefixed with "District "

Any thoughts on how to accomplish those two things?

ru flag
Does this answer your question? [How to use migrate process plugin concat on multiple values?](https://drupal.stackexchange.com/questions/307731/how-to-use-migrate-process-plugin-concat-on-multiple-values)
Lambic avatar
ph flag
I played around with using str_replace, but it doesn't recognise constants, so if I set replace to constants/ABC I get the literal "constants/ABC". Also I'm not sure how I would use that in the second scenario of setting field_display_name.
ru flag
Only the `source:` can contain a reference, all other keys are config and used by value. It might be *aesthetically pleasing* if provided with `constant/something`, but technically writing your string into `replace: 'foo'` is as hardcoded as writing it into `constants/something: 'foo'`
Lambic avatar
ph flag
Yeah that's why I can't use str_replace. The constant is coming from a Deriver so is different depending on which csv is being processed.
ru flag
EDIT: If you are using core version >9.2, you might create some crazy [callback with unpack_source](https://www.drupal.org/node/3205079)
Lambic avatar
ph flag
Thanks, that's the way things were looking, just wanted to confirm there wasn't an out-of-the-box way.. I'll post my plugin as an answer when I'm done.
ru flag
You might use the new v9.2 callback and create helper variables in your process section.
Score:1
ph flag

Here's the custom plugin I ended up writing:

<?php

namespace Drupal\mymodule\Plugin\migrate\process;

use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
use Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate;
use Drupal\migrate_plus\Plugin\migrate\process\EntityLookup;

/**
 * This plugin generates district entities within the process plugin.
 *
 * @MigrateProcessPlugin(
 *   id = "district_generate"
 * )
 *
 * @see EntityGenerate
 *
 * @code
 * process:
 *   field_political_district:
 *     plugin: district_generate
 *     source: jurisdiction
 *     district_set_name: constants/ABC
 *     district_set_value: "@_district_set"
 *     prefix: "District"
 *     ... other entityGenerate config
 * @endcode
 */
class DistrictGenerate extends EntityGenerate {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) {
    $this->row = $row;
    $this->migrateExecutable = $migrateExecutable;
    $name = $value;
    if (isset($this->configuration['district_set_name'])) {
      $suffix = $row->get($this->configuration['district_set_name']);
      $name = $name . ', ' . $suffix;
    }
    // Creates an entity if the lookup determines it doesn't exist.
    if (!($result = EntityLookup::transform($name, $migrateExecutable, $row, $destinationProperty))) {
      if (isset($this->configuration['district_set_value'])) {
        $this->configuration['values']['field_district_set'] = $this->configuration['district_set_value'];
      }
      $prefix = $this->configuration['prefix'] ?? 'District';
      $this->configuration['default_values']['field_display_name'] = $prefix . ' ' . $value;
      $result = $this->generateEntity($name);
    }
    return $result;
  }

}
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.