Closed (fixed)
Project:
Migrate
Version:
6.x-2.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
22 Dec 2010 at 10:45 UTC
Updated:
30 Jul 2011 at 07:34 UTC
Just came across the TODO tag "TODO: handle multiple values." in the class doc for MigrateFileFieldHandler in plugins/destinations/fields.inc.
Attached patch integrates multi value support.
The patch integrates a new argument to provide an additional separator. The one for the migration splits up the multiple values, and the new one splits up the image value in it's properties.
Now the input data can look like this:
/tmp/files/image|alternative name|my title|display_name#/tmp/files/2nd_image|2nd alternative name|Title for the 2nd file|display_name
To import this data you have to configure the field like this:
$arguments = MigrateFileFieldHandler::arguments(NULL, 'file_copy', NULL, NULL, 1, 2, NULL, 3, '|');
$this->addFieldMapping('field_images', 'images')
->separator('#')
->arguments($arguments);
| Comment | File | Size | Author |
|---|---|---|---|
| migrate-multivalue-support-for-file-fields.patch | 6.63 KB | das-peter |
Comments
Comment #1
scoff commentedpatch: **** malformed patch at line 80: $destination_file = file_stream_wrapper_uri_normalize($destination_dir . "/" . basename($full_path));
could you please attath or post a link to a full version of your fields.inc file?
Comment #2
das-peter commentedHi scoff,
I've created a repo on github:
https://github.com/das-peter/migrate/blob/master/plugins/destinations/fi...
Attention: There are other changes besides the file function, maybe you've to change some code. E.g. the stuff from #914440: Enhance multilingual support
$language = $this->getFieldLanguage($entity, $field_info, $arguments);.Comment #3
scoff commentedThank you!
Comment #4
mikeryanCommitted for D7, thanks! D6 filefield support is in migrate_extras at the moment, moving to that queue.
Comment #5
philipz commentedI can't get this to import multiple files into unlimited filefield - only first file gets imported.
I thought this separator argument is for multiple files but I understand now this is for additional file fields like alt and title.
I'll try to make this work for multiple files but maybe someone already did this or can point me to some information about this?
Comment #6
btmash commented@philipz, you are able to do multiple files with this patch. You would have something like:
So you would have 2 separators (in my case, I used '|' and '##'). The first separator is for separation of data related to a file and the second separator is for separation of files (so my data looked like '/path/to/file1|alt stuff|Title stuff##/path/to/file2|more alt stuff|other title'). My understanding is that the separator is built into what migrate does so it technically supports it for any field(? someone who has a better understanding of migrate would be able to correct me on this).
Comment #7
mikeryanFile field support moved back to Migrate.
Comment #8
markabur commentedI was having the same trouble as #5 until I added a non-null value for the new separator, even though I'm not actually using it (I'm just passing filenames, no metadata). Is that actually the intended behavior, to require both separators when doing multi-value file import?
Comment #9
philipz commentedThe #6 did the trick. I thought I tried something like that but now I don't remember. I had to put that away for a while.
Thanks BTMash!
Comment #10
mikeryanI committed the feature for packing an image's properties into the source field without looking too closely, and now I'm having second thoughts. Passing magic numbers (array indices) as arguments, frankly, grosses me out. Also, this means these arguments have three possible forms - a hard-coded string value, an array('source_field' => 'field_name') to pull the value from the source query, or a 3 to say "the value is in array index 3 of explode($separator, $image_properties)' I'm thinking about JSON as an alternative, but would like some input.
For the people using this technique, obviously it requires you to hack the source data to produce the format above. Exactly how are you introducing the separated properties? Is it in SQL in the source database; are you generating an intermediate table; is there a PHP or other programming step? Would it be difficult to replace the implode('|', $image_properties) (or its equivalent) with json_encode($image_properties)?
Thanks.
Comment #11
markabur commentedGood call, yeah, the indices are kind of mysterious.
I bumped into this but didn't end up using the separator/index part of it, so any kind of change here wouldn't affect my stuff (which actually is said and done at this point anyway). But I suppose if I was migrating that kind of metadata I'd expect to assemble the strings in php somehow.
Comment #12
btmash commentedOh, no, I'll have to change up my code! ^_~
I agree that the change into another format is probably a good idea; json works, or passing in an array in a similar way to how the actual file object looks also makes sense to me (so $row->files = array($file_1, $file_2, ...) with each file being an array (or object whichever you specify that has the orig. path, alt name, title name, description, etc) so we don't deal with some other source field(?).
Comment #13
mikeryanOK, done - file values can either be a path (either local or a URL), or a JSON-encoded array with the following members: url, alt, title, description, and display. When file properties are passed in via arguments, any properties present in the JSON override the arguments. See WineWineMigration in migrate_example for an example of how to use this support.
Next, to backport to D6...
Comment #14
mikeryanBackport was pretty simple, all done!
Comment #16
geerlingguy commentedJust FYI, to anyone coming in using 7.x-2.x, the method in #6 may not work (at least, I couldn't get it working after a few hours' effort). It turns out that the exact example of best practice is located inside wine.inc, in the WineWineMigration class. It shows you how to build a JSON array of all the file attachments, and pass that to the filefield properly. Much simpler to comprehend, too, considering how many arguments are in the #6 method :-P
Comment #17
btmash commented@geerlingguy, the method in #6 changed into the json method (and building out the attachments array in that manner) with the update from 2.0 to 2.1. And agreed, it is now *much* simpler to understand :)