I'm working on a D6 -> D8 migration, and my destination has a custom video upload field (field_video_upload) that contains three pieces of data: video, thumbnail, and poster (field_video_upload_video, field_video_upload_thumbnail, field_video_upload_poster respectively in the db). I'm attempting to migrate that data from my source table (actually a MySQL view) that has the data in a serialized format, and I'm using a custom source plugin to get the data.
public function prepareRow(Row $row) {
//TODO: Extract url from video_data field and video_thumb from thumbnail_data.
$video_data = get_object_vars(unserialize($row->getSourceProperty('video_data')));
$thumbnail_data = unserialize($row->getSourceProperty('thumbnail_data'));
// Get the array values. Seems to be the best way to work around having an
// array key of 0000000.
$video_data = reset($video_data);
$video_url = $video_data->url;
$video_thumb = $thumbnail_data['video_thumb'];
// Set the source properties.
$row->setSourceProperty('video_url', $video_url);
$row->setSourceProperty('video_thumb', $video_thumb);
}
}
Here is the relevant portion of the migration configuration .yml file:
field_video_upload:
plugin: video_upload
source:
- video_url
- video_thumb
and here is the custom process plugin video_upload to get the data:
namespace Drupal\migrate_mrctv\Plugin\migrate\process;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
/**
* This plugin gets values for the video upload field.
*
* @MigrateProcessPlugin(
* id = "video_upload"
* )
*/
class videoUpload extends ProcessPluginBase {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$video = array();
list($video_url, $video_thumb) = $value;
$video['video'] = $video_url;
// Use the same source thumb value for poster and thumb.
$video['thumbnail'] = $video_thumb;
$video['poster'] = $video_thumb;
return $video;
}
}
The source plugin works fine, and the data from the plugin is available in $value in videoUpload::transform(). However, none of the data is getting into this field in the node itself. The main node data is there, but no data for this field.
What do I need to change to get the data to import into my custom field?
Thanks.
UPDATE: In stepping through the Migrate code, I came across this line in Row->setDestinationProperty
:
NestedArray::setValue($this->destination, explode(static::PROPERTY_SEPARATOR, $property), $value, TRUE);
and since PROPERTY_SEPARATOR = '/'
, I tried this in my configuration:
'field_video_upload/video': video_url
'field_video_upload/thumbnail': video_thumb
'field_video_upload/poster': video_thumb
but no difference.
UPDATE 2: Based on the answer from @heddn below, I'm using the iterator plugin as part of a pipeline, since this is a multivalue field, even though it's set to only allow one value.
field_video_upload:
-
plugin: video_upload
source:
- video_url
- video_thumb
-
plugin: iterator
process:
video: video
thumbnail: thumbnail
poster: thumbnail
and modifying my plugin:
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$video = array();
list($video_url, $video_thumb) = $value;
$video[] = array(
'video' => $video_url,
// Use the same source thumb value for poster and thumb.
'thumbnail' => $video_thumb,
'poster' => $video_thumb
);
return $video;
}
}
This appears to work in that I the array from the video_upload plugin is passed as $value to the iterator plugin, but I'm still not getting values in field_video_upload. What else am I missing?