0

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.

1
  • 1
    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.
    – Hudri
    Feb 28, 2023 at 10:45

1 Answer 1

2

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;

      }

   }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.