Provide a migrate process plugin to parse text values

Created on 21 December 2021, over 3 years ago
Updated 11 April 2025, 7 days ago

Problem/Motivation

When migrating values from a text field into a name field, there is no process plugin to parse the components of the name out of the text.

Proposed resolution

A process plugin is provided below.

Remaining tasks

Include this code in the module at name/src/Plugin/migrate/process/NameField.php .

namespace Drupal\name\Plugin\migrate\process;

use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;

/**
 * Parses text values into name values.
 *
 * @MigrateProcessPlugin(
 *   id = "name_field"
 * )
 */
class NameField extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    // Get rid of any leading or trailing spaces.
    $value = trim($value);
    // Get rid of any duplicate spaces.
    $value = preg_replace('/  +/', ' ', $value);
    $words = explode(' ', $value);
    if (count($words) == 1) {
      // Assume just a credential.
      return ['credentials' => $value];
    }
    
    // Focus on credentials first.
    $paren = strpos($value, '(');
    $close = strpos($value, ')');
    $slash = strpos($value, '/');
    $dash = strpos($value, ' -') ?: strpos($value, '- ');
    $comma = strpos($value, ',');
    $creds = ['Attorney', 'CEO', 'Chef', 'Pastor', 'President'];
    $gen = ['Jr.', 'II', 'III', 'IV', 'V'];
    $parsed = [];
    if ($paren && $close > $paren) {
      // Assume credentials are in the parentheses.
      $parsed['credentials'] = trim(substr($value, $paren + 1, $close - $paren - 1));
      $value = substr($value, 0, $paren);
    }
    elseif ($comma && $slash > $comma) {
      // Assume credentials follow the comma and contain a slash.
      $parsed['credentials'] = trim(substr($value, $comma + 1));
      $value = substr($value, 0, $comma);
    }
    elseif (in_array(trim($words[0]), $creds)) {
      // First word is credential.
      $parsed['credentials'] = trim(array_shift($words));
      $value = substr($value, strpos($value, ' '));
    }
    elseif ($slash) {
      // Assume credentials follow the slash.
      $parsed['credentials'] = trim(substr($value, $slash + 1));
      $value = substr($value, 0, $slash);
    }
    elseif ($dash) {
      // Assume credentials follow the dash & space.
      $parsed['credentials'] = trim(substr($value, $dash + 2));
      $value = substr($value, 0, $dash);
    }
    elseif ($comma) {
      $after = trim(substr($value, $comma + 1));
      // Check for generational.
      if (in_array($after, $gen)) {
        $parsed['generational'] = $after;
      }
      else {
        // Assume credentials follow the comma.
        $parsed['credentials'] = $after;
      }
      $value = substr($value, 0, $comma);
    }
    elseif (in_array(trim(end($words)), $creds)) {
      // Last word is credential.
      $parsed['credentials'] = array_pop($words);
      $value = substr($value, 0, strrpos($value, ' '));
    }

    // Now that credentials are out of the way, let's look at what's left.
    $words = explode(' ', trim($value, " \t,/()-"));
    $titles = ['Dr.', 'Mr.'];
    if (in_array(trim($words[0]), $titles)) {
      // First word is title.
      $parsed['title'] = trim(array_shift($words));
    }
    if (in_array(trim(end($words)), $gen)) {
      // Final word is generational.
      $parsed['generational'] = trim(array_pop($words));
    }
    // Assume first remaining word is given name.
    $parsed['given'] = trim(array_shift($words));
    if (count($words) > 1) {
      // Assume first remaining word is middle name.
      $parsed['middle'] = trim(array_shift($words));
    }
    // Assume everything remaining is the family name.
    $parsed['family'] = trim(implode(' ', $words));
    
    return $parsed;
  }

}

To use this in a migration:

process:
  field_name:
    plugin: name_field
    source: field_name_text/0/value
✨ Feature request
Status

Needs work

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States BenStallings

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024