Score:0

I need help migrating a mulit-value link field from string w/ 2 delimiters

kr flag

I'm trying to migrate a node bundle from one drupal 9 application to another.

My source format is an XML document.

I'm stuck migrating a multi-value link field.

Both the source and destination machine names are field_quicklinks.

The source value is a string with two delimiters like the following.

"https://www.somedomain.org/somewhere/something.pdf*Something Document^https://www.someotherdomain.org/somewhere-else/some-other-document.pdf*Some Other Document^https://www.yetsomeotherdomain.org/yet-somewhere-else/yet-another-document.pdf*Yet Another Document"

So my intent is to explode this twice to look like:

[
  [
    "https://www.somedomain.org/somewhere/something.pdf",
    "Something Document"
  ],
  [
    "https://www.someotherdomain.org/somewhere-else/some-other-document.pdf",
    "Some Other Document"
  ],
  [
    "https://www.yetsomeotherdomain.org/yet-somewhere-else/yet-another-document.pdf",
    "Yet Another Document"
  ]
]

The latest iteration of my attmpts looks like:

field_quicklinks:
    -
      plugin: skip_on_value
      method: process
      value: FIELD_EMPTY
      source: field_quicklinks
    -
      plugin: explode
      source: field_quicklinks
      delimiter: '^'
    -
      plugin: multiple_values
      source: field_quicklinks
    -
      plugin: explode
      source: field_quicklinks
      delimiter: '*'
    -
      plugin: sub_process
      source: field_quicklinks
        process:
          field_quicklinks/uri:
              plugin: callback
              source: field_quicklinks
              callable: array_shift
    -
      plugin: sub_process
      source: field_quicklinks
      process:
        field_quicklinks/title:
            plugin: callback
            source: field_quicklinks
            callable: array_pop

If somebody could get me on track I would of course appreciate it very much.

ru flag
Very first thing I see here: Do not use `source: field_quicklinks` in chained process plugins, because you do not want sub-sequent process plugins to work on the original `field_quicklinks`. Instead omit the `source` key, so the output of the previous plugin is used as input for the next plugin. Only the first process plugin should have a `source`.
Score:2
kr flag

So I'm betting there's an existing way to accomplish this but I was spending way too much time on it and decided to create a custom process plugin.

The relevant part of my migration yaml looks like:

field_quicklinks_array:
    -
      plugin: skip_on_value
      method: process
      value: FIELD_EMPTY
      source: field_quicklinks
    -
      plugin: str_with_two_delimiters
field_quicklinks:
    plugin: sub_process
    source: '@field_quicklinks_array'
    process:
      uri: uri
      title: title

My custom process plugin which I placed here:

web/modules/custom/my_bundle_migration/src/Plugin/migrate/process/ParseStringWithTwoDelimiters.php

looks like:

<?php

  namespace Drupal\my_bundle_migration\Plugin\migrate\process;

  use Drupal\migrate\ProcessPluginBase;
  use Drupal\migrate\MigrateException;
  use Drupal\migrate\MigrateExecutableInterface;
  use Drupal\migrate\Row;
  /**
   * This plugin converts a string with two delimiters into an array of arrays
   *
   * @MigrateProcessPlugin(
   *   id = "str_with_two_delimiters"
   * )
   */
   class ParseStringWithTwoDelimiters extends ProcessPluginBase {
     /**
      * {@inheritdoc}
      */
      public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
        $prelim_results_array = [];
        $final_results_array = [];
        $array_one = explode("^",$value);
        foreach ($array_one as $element) {
          array_push($prelim_results_array,explode("*",$element));
        }
        foreach($prelim_results_array as $v){
          array_push($final_results_array,['uri' => $v[0], 'title' => $v[1]]);
        }

        return $final_results_array;

      }

   }
I sit in a Tesla and translated this thread with Ai:

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.