Modifying Rows During a Drupal 8 CSV Migration

Migrate Source CSV is currently the source plugin of choice for doing a CSV-to-Drupal migration with the Migrate API in Drupal 8. In this post I will demonstrate how to manipulate the CSV data in realtime during the migrate:import operation. You can think of this as the equivalent to prepareRow() that you have seen elsewhere, like my blog post Extending the Migrate Plus JSON Parser in Drupal 8.

Please make sure you have a working migration before you begin; it’ll make things easier to troubleshoot if you know you had a good starting point.

Here’s an example of a simple Drupal 8 migration that I’m working on. I removed all of the fields except a few needed to illustrate the solution. This setup migrates CSV data (tab-delimited) from a 3rd party into a “Directory Entry” content type. The machine name of the content type is direntry. The fields in this content type are shown under column_names in the migration YML.

Module Code Before Overriding

The file structure is:

Here are each of the files, before we add our class to override row data:

migrate_plus.migration.mysite_direntry_nodes.yml

migrate_plus.migration_group.mysite_directory.yml

mysite_migrate.info.yml

Manipulating Row Data

You can manipulate data by changing the file class that the source plugin uses. If you have a look at \Drupal\migrate_source_csv\Plugin\migrate\source\CSV::defaultConfiguration  you will find a default file_class of Drupal\migrate_source_csv\CSVFileObject is used. Within this class you will find a current()  method that updates the row data to be keyed by column name (as defined in your YML).

To manipulate the row data you must override this current()  method in your own file class. Here’s what that looks like:

First, we modify the migrate_plus.migration.mysite_direntry_nodes.yml source plugin configuration to use a new file class.

Next, we create the file class, which we place in mysite_migrate/src/DirectoryEntryNodeCsvFileObject.php.

Don’t forget to enable your mysite_migrate module and clear the cache so the new class is picked up.

All that is left is to test! I recommend testing with a single record. Here’s an example:

You can run this as many times as you’d like while you work out the logic for your current()  method.

After I run this for the first time, one record is created with a title of “Testing Override Capabilities” as expected, because the fullname column is mapped to the title in the process section of the YML.

Tagged with: , , , ,
Posted in Development

Leave a Reply

Your email address will not be published. Required fields are marked *

*