0

I'm a bit at the end of my rope in trying to get file fields to show up as possible destinations for my Media module migration. I have Media 7.1.x installed because as best I can tell, that must be the version that Migrate Extras was supporting. I'm trying to import files into the Other file type, so I have the following:

$this->destination = new MigrateDestinationMedia('other');
$this->map = new MigrateSQLMap($this->machineName,
      array(
        'id' => array(
          'type'        => 'int',
          'length'      => 11,
          'not null'    => TRUE,
          'description' => 'File ID',
          'alias'       => 'f',
        ),
      ),
      MigrateDestinationMedia::getKeySchema()
    );

Unfortunately I cannot get the field I added to the Other file type to show up as an available destination field in Migrate UI. Any help on what I'm doing wrong here, or even a code snippet where someone has successfully done a media migration (for files, not youtube or anything fancy like that), would be greatly appreciated!

Update: I'm most of the way there, but my fields still aren't coming in. Here is the array I created:

I create a $row->fields_array that looks like:

[fields_array] => Array
    (
        [0] => Array
            (
                [field_doc_public] => 1
                [field_testing_testing_testing] => UE2_3009.pdf
            )

        [1] => Array
            (
                [field_doc_public] => 0
                [field_testing_testing_testing] => UE2_3009.doc
            )

    )

I really only need the field_doc_public field to be filled in, but I added field_testing_testing_testing to test as you might guess from the name. The field machine names are field_doc_public and field_testing_testing_testing.

The code in the actual migration looks like:

    $this->addFieldMapping('field_doc_pub_files', 'file_source_file');
    $this->addFieldMapping('field_doc_pub_files:file_class')
        ->defaultValue('MigrateEntityFileUri');
    $this->addFieldMapping('field_doc_pub_files:fields', 'fields_array')
        ->description(t('Populate the fields.'));
    $this->addFieldMapping('field_doc_pub_files:destination_dir')
        ->defaultValue('private://pub_docs');
    $this->addFieldMapping('field_doc_pub_files:destination_file', 'file_dest_filename');
    $this->addFieldMapping('field_doc_pub_files:file_replace')
        ->defaultValue(MigrateFileBase::FILE_EXISTS_REUSE);
    $this->addFieldMapping('field_doc_pub_files:preserve_files')
        ->defaultValue(FALSE);
    $this->addFieldMapping('field_doc_pub_files:display', file_public);

Any help on that last little push over the finish line would be greatly appreciated. (Note: no destination for the fields shows up in Migrate UI either)

1 Answer 1

2

The following will allow you to use Migrate to import files as File Entities (used for Media 2.x) and populate the File Entity fields when importing Nodes (MigrateDestinationNode). No Migrate Extras needed.

Add the following to your custom migrate module's .info file:

files[] = includes/MigrateEntityFileUri.inc

Download/save the following code in an "includes" subfolder of your migrate module. (Strip the .php extension) https://gist.github.com/dmsmidt/6f0f498a9dbaea8602fb

Then in your Migration class you can use 'MigrateEntityFileUri' as file_class.

Example code:

$this->addFieldMapping('field_media', 'your_file_uri_source_array');
$this->addFieldMapping('field_media:file_class')
  ->defaultValue('MigrateEntityFileUri');
$this->addFieldMapping('field_media:fields', 'fields_array')
  ->description(t('Populate the fields.'));
$this->addFieldMapping('field_media:destination_dir')
  ->defaultValue('public://your_file_sub_dir');
$this->addFieldMapping('field_media:file_replace')
  ->defaultValue(MigrateFileBase::FILE_EXISTS_REUSE);
$this->addFieldMapping('field_media:preserve_files')
  ->defaultValue(TRUE);

Note the sources: 'your_file_uri_source_array' and 'fields_array'. You may need to do some processing in prepareRow() depending on your source to get your data organized like this (pseudocode):

public function prepareRow($row) {
    $row->fields_array = array(
      array(
        'field_one' => 'value_field_file_one',
        'field_two' => 'value_field_file_one'
      ),
      array(
        'field_one' => 'value_field_file_two',
        'field_two' => 'value_field_file_two'
      ), 
    );
    $row->your_file_uri_source_array = array('file_one_uri', 'file_two_uri');
  }
7
  • Thanks! I'lll work on implementing this now, and come back and accept the answer if I manage to get it working.
    – UltraBob
    Commented Jan 20, 2016 at 1:21
  • I'm mostly there, but the fields still aren't coming across. I updated my question. Could you please have a look?
    – UltraBob
    Commented Jan 20, 2016 at 7:21
  • Have you confirmed this code works for you? When I run through the migration it looks up a schema that doesn't include my custom files and then walks through the fields in that schema determining what to write. The values from my array are carried along through the entire process, but seem never to get used anywhere.
    – UltraBob
    Commented Jan 21, 2016 at 0:50
  • doesn't include my custom fields, not custom files
    – UltraBob
    Commented Jan 21, 2016 at 6:20
  • OK, this answer doesn't quite do it. It is the best answer so far, but that file class is not causing the fields to be written. I'm not sure at what stage or in what method that would normally occur, so I haven't been able to track down what is going wrong. Going through the debugger it does walk through the custom field array a number of times setting up like it is going to go something. Once it even checks for the availability of fieldtype_field_insert methods, but that is in the file handling section. I'm probably going to give up and have two file fields one for public, one for not.
    – UltraBob
    Commented Jan 21, 2016 at 10:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.