Can anyone suggest a way to dynamically assign the file path when setting arguments in MigrateFileFieldHandler?

Here's what I'm trying to do: I have a legacy file system where images are stored in a directory that looks something like 'assets/month/year'. The month and year are variables stored in a legacy table. I want to maintain that same structure in the new migration so that I can just copy the whole assets folder into the Drupal files directory. My problem is that I don't know how to retrieve the month and year variables from the old table and apply them in the MigrateFile Field Handler.

(That's probably not all that clear, but hopefully this makes more sense: In the wine.inc example, the code looks like this:

 $arguments = MigrateFileFieldHandler::arguments(drupal_get_path('module', 'migrate_example'), 'file_copy', FILE_EXISTS_RENAME);

I want to do something like this:

 $arguments = MigrateFileFieldHandler::arguments($path_retrieved_from_legacy_db, 'file_copy', FILE_EXISTS_RENAME);

Any help is appreciated.

Comments

silkyD’s picture

I was able to finally solve this issue by moving the arguments and field mapping call into a prepareRow method within the class. (Doing this will spit out multiple warnings in drush saying the field was previously mapped, but it seems to work. If anyone has a better solution, please let me know. Maybe move the mapping into 'prepare' instead of 'prepareRow'? Maybe doing something entirely different?)

Anyway, in the interest of helping anyone else out, here's what I did...

1) Create a prepareRow method within the class. (See the wine.inc example at line 449.)
2) Within the prepareRow method, create an argument based on your migration variables. It might look something like this:

public function prepareRow($current_row) {
//...misc code goes here. (see wine.inc example) 
$arguments = MigrateFileFieldHandler::arguments($row->path_retrieved_from_legacy_db, 'file_copy', FILE_EXISTS_RENAME);

3) Set the field mapping exactly as outlined in the wine example, but do it within the prepareRow method:

public function prepareRow($current_row) {
//...misc code goes here. (see wine.inc example) 
$arguments = MigrateFileFieldHandler::arguments($row->path_retrieved_from_legacy_db, 'file_copy', FILE_EXISTS_RENAME);
$this->addFieldMapping('field_migrate_example_image', 'image')
         ->arguments($arguments);
//etc....

That's it. Like I said, I don't know if there are any ramifications to setting field mapping within the prepareRow method, but so far, this seems to work.

mikeryan’s picture

Status: Active » Postponed (maintainer needs more info)

Wouldn't this be simpler?

public function prepareRow($current_row) {
  $row->image = $current_row->path_retrieved_from_legacy_db . '/' . $current_row->image;
}
silkyD’s picture

My issue wasn't in setting the file path, it was sending it to the arguments in MigrateFileFieldHandler for each item I was trying to migrate. (Sorry if I'm missing something. Here's my reasoning...)

Because the image was a CCK file field, I think you have to use the MigrateFileFieldHandler. (I mean, you can't just skip setting the ->arguments portion of a file field, right?)

The only way I was able to get that to work was to move the MigrateFileFieldHandler arguments and Field Mapping inside the prepareRow function.

Is there some other way to do this?

*Thanks for this, BTW: I am absolutely loving this module.

mikeryan’s picture

You set the arguments and field mapping as normal in the constructor (setting the path to the root under which you want the files to go). My point is that, rather than trying to change the base path, you should be able to just prepend the subpath to your filename.

silkyD’s picture

(Queue sound effect of hand slapping forehead.)

Of course!

That's exactly the way to do it.

Thanks, Mike!

mikeryan’s picture

Status: Postponed (maintainer needs more info) » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

webdrips’s picture

Status: Closed (fixed) » Active

Hi Mike.

(EDIT: I found the answer for filefields using JSON data like how wine.inc handled it, but links don't support JSON data, so I'm editing my original question).

I have a similar issue, but instead of the file path, I want to set the title dynamically for a link.

The only place I could think to do this was in prepareRow(), but then the argument won't be ready "in time" since the field mappings are part of the constructor.

Here's what I'm attempting to do in prepareRow():

    $has_url = (!empty($current_row->em_url)) ? "Y" : "N";        
    if ($has_url == 'Y') {
      $arguments_url = MigrateLinkFieldHandler::arguments($current_row->title, NULL, NULL); 
    }

I've searched and searched and don't see anything quite like it. Of course, this gets even more fun with multiple links, but I'd be happy to get it working properly for one. As a side note, if I add the mapping within prepareRow() (which of course causes warnings each row), I can at least set the title for the first URL, but I'd like to do this correctly if possible.

Thanks in advance,

Dan

mikeryan’s picture

Status: Active » Fixed

Please don't reopen closed issues to add off-topic questions.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.