Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I am following this example in wine.inc:
// TIP: You can apply one or more functions to a source value using
// ->callbacks(). The function must take a single argument and return a
// value which is a transformation of the argument. As this example shows,
// you can have multiple callbacks, and they can either be straight
// functions or class methods. In this case, our custom method prepends
// 'review: ' to the body, and then we call a standard Drupal function to
// uppercase the whole body.
$this->addFieldMapping('body', 'body')
->callbacks(array($this, 'addTitlePrefix'), 'drupal_strtoupper');
$this->addFieldMapping('body:summary', 'excerpt');
However, in my callback, I am performing a transformation to the value based on a mapping:
protected function myFieldMappingCallback($source_data) {
$map = array(
'green' => 'apple',
'yellow' => 'banana',
);
if (!isset($map[$source_data)) {
// Log a message.
return 'unknown';
}
return $map[$source_data];
}
I'd obviously like to include some details in the message I log, such as the row ID. But AFAIK I can't access that from inside the callback.
I suggest that the callback have a $row parameter added to its signature.
Comment | File | Size | Author |
---|---|---|---|
#6 | 2223057.migrate.field-mapping-callback-row-param.patch | 1.95 KB | joachim |
Comments
Comment #1
13rac1 CreditAttribution: 13rac1 commentedYou can do this in prepareRow() without changing the module.
Comment #2
joachim CreditAttribution: joachim commentedYes, definitely.
However, I got the impression that using a callback for this was preferable. Certainly from my point of view it's cleaner, as it segments the different parts of the pre-processing into different methods: instead of one giant prepareRow() method that's hard to read, there's a series of callback methods, each of which has a single task to perform.
Comment #3
13rac1 CreditAttribution: 13rac1 commentedInstead of a large prepareRow(), you can make separate functions for each "prepareField". I'm almost to the point doing that on my main migration.
Comment #4
joachim CreditAttribution: joachim commentedTrue -- but if you do that, then why bother having the callback at all?
Comment #5
13rac1 CreditAttribution: 13rac1 commentedI'm using the callbacks for simple formatting. Here is one that I'm using to make sure the title doesn't cause SQL problems. I'm getting the full title in a long text field:
But, yeah, you can argue against the existence of callbacks.
Comment #6
joachim CreditAttribution: joachim commentedThis has come up again on a different project.
Here's a patch.
Comment #8
joachim CreditAttribution: joachim commentedHmm, possibly redundant now I look at it some more, as you can use $this->sourceValues in the migration class.
But then, methods such as prepareRow() work with a $row parameter, so would be nice to be consistent.