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

Issue fork name-3255533

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

BenStallings created an issue. See original summary.

liam morland’s picture

Version: 8.x-1.0-rc3 » 8.x-1.x-dev
Status: Needs review » Needs work

Please put these changes into an issue fork and merge request.

tyapchyc’s picture

Assigned: Unassigned » tyapchyc
Status: Needs work » Active

tyapchyc’s picture

Assigned: tyapchyc » Unassigned
Status: Active » Needs review

bluegeek9 made their first commit to this issue’s fork.

bluegeek9 changed the visibility of the branch 8.x-1.x to hidden.

bluegeek9’s picture

Status: Needs review » Needs work

The plugin needs tests.

It would be better if values were not hard coded. I am open to suggestions. I guess it could use the values in the field instance of the destination.

$creds = ['Attorney', 'CEO', 'Chef', 'Pastor', 'President'];
$gen = ['Jr.', 'II', 'III', 'IV', 'V'];
$titles = ['Dr.', 'Mr.'];

It appears that this plugin is very opinionated on how names will be formatted. Maybe there is away to use a name format as an argument to the plugin?

benstallings’s picture

Assigned: Unassigned » benstallings
benstallings’s picture

Assigned: benstallings » Unassigned
Status: Needs work » Needs review

Here you go, @bluegeek9!

bluegeek9’s picture

It is hard to tell what the transform method is doing. Can we refactor using protected or private methods?

https://issue.pages.drupalcode.org/-/name-3255533/-/jobs/9378971/artifac...

bluegeek9’s picture

Status: Needs review » Fixed
//www.flaticon.com/free-icons/thank-you Thank you for your contribution! Your continued support makes this project sustainable.
There are multiple ways to show appreciation for the work contributed to this project including:

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • bluegeek9 committed 6216ce3b on 8.x-1.x authored by tyapchyc
    fix: #3255533 Provide a migrate process plugin to parse text values
    

Status: Fixed » Closed (fixed)

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