My client is crazy about pictures in content types. I need to have prepareRow in 75% of my migrate subclasses to translate the D6 FID to D7. It may be that I don't know what example to look at, but I would appreciate an example of a function migrating the FID after I have migrated the images. My version of prepareRow below does not properly map the D6 FID to D7 FID. I do know that the mapping is provided in migrate_map_file_managed.

/**
 * Manipulate any data in the source row that needs to be manipulated before
 * the destination row is filled. Currently for Horse this is only the
 * field_horse_pictures image which needs the files table FID replaced with the
 * file_managed table FID.
 */
  public function prepareRow($row) {
    if (parent::prepareRow($row) === FALSE) {
      return FALSE;
    }
    $msg = "entering prepareRow row = " . print_r($row, TRUE);
    watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
    // The file ID for the horse pictures needs to be translated from the Drupal 6 fid to
    // the new Drupal 7 fid.
    if (!empty($row->field_horse_pictures)) {
      $msg = "prepareRow field_horse_pictures = " . $row->field_horse_pictures;
      watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
      $destination_ids = $this->getMap()->lookupDestinationID(array($row->field_horse_pictures));
      if (empty($destination_ids)) {
        $msg = "destination_ids is empty in prepareRow";
        watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
      }
      else {
        $row->field_horse_pictures = $destination_ids['destid1'];
        $msg = "prepareRow field_horse_picture Set to " .$row->field_horse_pictures;
        watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
      }
    }
    else {
        watchdog("Horse Migration", "field_horse_pictures is empty", NULL, WATCHDOG_DEBUG, NULL);
    }
    $msg = "exiting prepareRow row = " . print_r($row, TRUE);
    watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
    return TRUE;
  }

I list the entire sublcass below, SetUpFieldMappings is called in spectackulard6tod7_NonProducts_Migration, the local migration arguments are also processed in spectackulard6tod7_NonProducts_Migration.

class spectackulard6tod7_Horse_Migration extends spectackulard6tod7_NonProducts_Migration
{
  protected function SetUpFieldMappings()
  {
    $this->addFieldMapping('field_horse_breed_primary_', 'field_horse_breed')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_breed_secondary', 'field_horse_breed_secondary')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_gender', 'field_horse_gender')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_primary_color', 'field_horse_color_primary')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_pattern', 'field_horse_pattern')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_secondary_color', 'field_horse_color_secondary')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_markings', 'field_horse_markings')
         ->defaultValue('None Selected');
//    $this->addFieldMapping('field_horse_date_foaled', 'field_horse_birth');
    $this->addFieldMapping('field_horse_primary_riding_disci', 'field_horse_riding_disc_primary')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_other_riding_discipl', 'field_horse_riding_disc_other')
         ->defaultValue('None Selected');
    $this->addFieldMapping('field_horse_msmt_smile2smile', 'field_horse_msmt_smile2smile');
    $this->addFieldMapping('field_horse_msmt_nose', 'field_horse_msmt_nose');
    $this->addFieldMapping('field_horse_msmt_ns2s', 'field_horse_msmt_ns2s');
    $this->addFieldMapping('field_horse_msmt_throat', 'field_horse_msmt_throat');
    $this->addFieldMapping('field_horse_msmt_browband', 'field_horse_msmt_browband');
    $this->addFieldMapping('field_horse_msmt_head_gear_size', 'field_horse_msmt_head_gear_size');
    $this->addFieldMapping('field_horse_msmt_saddle_ring', 'field_horse_msmt_saddle_ring');
    $this->addFieldMapping('field_horse_msmt_saddle_cinch', 'field_horse_msmt_saddle_cinch');
    $this->addFieldMapping('field_horse_msmt_brstcollar_size', 'field_horse_msmt_brstcollar_size');
    $this->addFieldMapping('field_horse_msmt_reins_width', 'field_horse_msmt_reins_width');
    $this->addFieldMapping('field_horse_msmt_reins_style', 'field_horse_msmt_reins_style');
    $this->addFieldMapping('field_horse_msmt_reins_length', 'field_horse_msmt_reins_length');
    $this->addFieldMapping('field_horse_picture', 'field_horse_pictures')
         ->sourceMigration('horse');
    $this->addFieldMapping('field_horse_picture:file_class')
         ->defaultValue('MigrateFileFid');
    $this->addFieldMapping('field_horse_picture:preserve_files')
         ->defaultValue(TRUE);
    $this->addFieldMapping('field_horse_picture:language')
         ->defaultValue(LANGUAGE_NONE);
  }

/**
 * Manipulate any data in the source row that needs to be manipulated before
 * the destination row is filled. Currently for Ambassador this is only the
 * bio_pic image which needs the files table FID replaced with the
 * file_managed table FID.
 */
  public function prepareRow($row) {
    if (parent::prepareRow($row) === FALSE) {
      return FALSE;
    }
    $msg = "entering prepareRow row = " . print_r($row, TRUE);
    watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
    // The file ID for the horse pictures needs to be translated from the Drupal 6 fid to
    // the new Drupal 7 fid.
    if (!empty($row->field_horse_pictures)) {
      $msg = "prepareRow field_horse_pictures = " . $row->field_horse_pictures;
      watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
      $destination_ids = $this->getMap()->lookupDestinationID(array($row->field_horse_pictures));
      if (empty($destination_ids)) {
        $msg = "destination_ids is empty in prepareRow";
        watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
      }
      else {
        $row->field_horse_pictures = $destination_ids['destid1'];
        $msg = "prepareRow field_horse_picture Set to " .$row->field_horse_pictures;
        watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
      }
    }
    else {
        watchdog("Horse Migration", "field_horse_pictures is empty", NULL, WATCHDOG_DEBUG, NULL);
    }
    $msg = "exiting prepareRow row = " . print_r($row, TRUE);
    watchdog("Horse Migration", $msg, NULL, WATCHDOG_DEBUG, NULL);
    return TRUE;
  }

 /**
   * Implements Migration::prepare().
   *
   * @param $MyHorse
   * @param $row
   */
  public function prepare($MyHorse, $row) {
  // no debug information for the time being because there are too many of these.
  }

  public function __construct($arguments) {
    $localUnmigratedSources = array(
      'revision', 'log', 'revision_uid', 'field_horse_pictures:list',
      'field_horse_birth',
    );
    $arguments['Local_UnMigrated_Sources'] = $localUnmigratedSources;
    $localUnmigratedDestinations = array(
      'field_horse_date_foaled',
      'field_horse_breed_primary_:source_type',
      'field_horse_breed_primary_:create_term',
      'field_horse_breed_primary_:ignore_case',
      'field_horse_breed_secondary:source_type',
      'field_horse_breed_secondary:create_term',
      'field_horse_breed_secondary:ignore_case',
      'field_horse_gender:source_type',
      'field_horse_gender:create_term',
      'field_horse_gender:ignore_case',
      'field_horse_primary_color:source_type',
      'field_horse_primary_color:create_term',
      'field_horse_primary_color:ignore_case',
      'field_horse_secondary_color:source_type',
      'field_horse_secondary_color:create_term',
      'field_horse_secondary_color:ignore_case',
      'field_horse_pattern:source_type',
      'field_horse_pattern:create_term',
      'field_horse_pattern:ignore_case',
      'field_horse_markings:source_type',
      'field_horse_markings:create_term',
      'field_horse_markings:ignore_case',
      'field_horse_date_foaled:timezone',
      'field_horse_date_foaled:rrule',
      'field_horse_date_foaled:to',
      'field_horse_primary_riding_disci:source_type',
      'field_horse_primary_riding_disci:create_term',
      'field_horse_primary_riding_disci:ignore_case',
      'field_horse_other_riding_discipl:source_type',
      'field_horse_other_riding_discipl:create_term',
      'field_horse_other_riding_discipl:ignore_case',
      'field_horse_picture:alt',
      'field_horse_picture:title',
    );
    $arguments['Local_UnMigrated_Destinations'] = $localUnmigratedDestinations;
    parent::__construct($arguments);
  }
}

How I migrate all the image files:

<?php

class spectackulard6tod7_File_Migration extends DrupalFile6Migration
{
  /*
   * There are common field in most tables that won't be migrated, or may be migrated
   * later by other migration modules.
   */
  protected $CommonUnMigratedSources;
  protected $CommonUnMigratedDestinations;

  protected function CommonUnMigratedFields()
  {
    $this->CommonUnMigratedSources = array();
    $this->CommonUnMigratedDestinations = array();

    $CommonUnMigratedSources = spectackulard6tod7_Common_UnMigratedSources();
    $CommonUnMigratedDestinations = spectackulard6tod7_Common_UnMigratedDestinations();

    $this->CommonUnMigratedSources += $CommonUnMigratedSources;
    $this->CommonUnMigratedDestinations = $CommonUnMigratedDestinations;
  }

  protected $LocalUnMigratedSources;
  protected $LocalUnMigratedDestinations;

  protected function LocalUnMigratedFields()
  {
    $this->LocalUnMigratedDestinations = array('path', 'urlencode');
    if (isset($this->arguments['Local_UnMigrated_Sources']))
    {
      $this->LocalUnMigratedSources = $this->arguments['Local_UnMigrated_Sources'];
    }
    else
    {
      $this->LocalUnMigratedSources = array();
    }
  }

  protected function SetUpMigrations()
  {
    $this->CommonUnMigratedFields();
    $this->LocalUnMigratedFields();

    $unmigratedSources = $this->LocalUnMigratedSources + $this->CommonUnMigratedSources;
    $unmigratedDestinations = $this->LocalUnMigratedDestinations + $this->CommonUnMigratedDestinations;

    if (count($unmigratedDestinations) > 0) {
      $this->addUnmigratedDestinations($unmigratedDestinations);
    }
    if (count($unmigratedSources) > 0) {
      $this->addUnmigratedSources($unmigratedSources);
    }
  }

  protected function SetUpFieldMappings()
  {
    $this->addFieldMapping('fid', 'fid', TRUE);
    $this->addFieldMapping('uid', 'uid', TRUE);
    $this->addFieldMapping('filename', 'filename, TRUE');
    $this->addFieldMapping('filepath', 'filepath, TRUE');
    $this->addFieldMapping('filemime', 'filemime, TRUE');
    $this->addFieldMapping('filesize', 'filesize, TRUE');
    $this->addFieldMapping('status', 'status', TRUE);
    $this->addFieldMapping('timestamp', 'timestamp', TRUE);
  }


  public function __construct(array $arguments) {
    parent::__construct($arguments);

//    $this->SetUpFieldMappings();

    $this->SetUpMigrations();
  }
}

function spectackulard6tod7_BuildFileArguments()
{
  $file_arguments = array(
// using the default destination directory.
    'class_name' => 'spectackulard6tod7_File_Migration',
    'machine_name' => 'file_managed',
    'description' => t('Migration of SpecTACKular files including images from Drupal 6'),
    'source_dir' => '/home/pacmaninbw/backups/public_html',
    'default_uid' => 1,
    'user_migration' => array('user'),
    'dependencies' => array('user'),
  );

  return $file_arguments;
}

Comments

mikeryan’s picture

Status: Active » Postponed (maintainer needs more info)

I really don't have time to review all that code, but is there a reason you can't just use sourceMigration?

$this->addFieldMapping('field_pictures', 'field_legacy_picture_field')
     ->sourceMigration('MyFileMigration');
$this->addFieldMapping('field_pictures:file_class')
     ->defaultValue('MigrateFileFid');
pcher1bw’s picture

Because I misread the example on https://www.drupal.org/node/1819704.

Just another user error, sorry. The images are migrating fine now that you pointed that out to me.

Sorry for wasting your time.

mikeryan’s picture

Status: Postponed (maintainer needs more info) » Closed (works as designed)