Problem/Motivation
Sorry for the blunt issue title, I still don't grok exactly what is happening here to denote a more specific problem. It might be that I'm just using the system wrong but in that case the documentation is severely lacking and/or the code paths are fairly ungrokable.
As part of migrating a D6 site to D8 I utilized the d6_user migration that core ships with. I made some minor modifications for our use-case (such as not migrating the text formats for the user signatures but just using a static map) but left it as is almost completely.
However, when executing, the migration did not complete for me. Especially the migration of the user pictures failed. Here's the path down the rabbit hole:
- I noticed that something in
\Drupal\migrate\Plugin\migrate\destination\EntityFile::import()went wrong.$this->configuration['source_path_property']waspicturebut the passed row did not have a correspondingpictureproperty. - That is because
\Drupal\migrate\Plugin\migrate\process\Migration::transform()(which performs thed6_user_picture_filemigration as part of thed6_usermigration) creates a$stub_rowwhich only contains the ID values of the source (here: the source of the
d6_user_picture_filemigration).\Drupal\migrate_drupal\Plugin\migrate\source\d6\UserPictureFile::getIds(), however, simply declares theuidas an ID. - That's why the attached patch adds the
picturecolumn there as well. - Even then, though, the
$stub_rowdoes not contain the correct values because$source_id_values[$migration_id]is empty. - That in turn is because
$valueis passed asNULLintoMigration::transform()so one would have to fill$this->configuration['source_ids'][$migration_id]for$source_id_valuesto be set correctly (see lines 88 and following ofMigration.php). - Setting
source_idsin the parent migration (i.e. ind6_user) does not have any effect, though, because\Drupal\migrate_drupal\Plugin\migrate\process\d6\UserPicture::createdoes not pass down the passed$configurationinto theMigrationplugin but instead creates the child configuration (i.e. that of thed6_user_picture_filemigration) from scratch. - That is why the patch adds the passing down of
source_idsinUserPicture. At that point$sourceinEntityFileactually gets set to the correct value. $destination, however, is empty. That is because the processed$stub_rowdoes not contain auriproperty.- The
$migration(inMigration::transform(), i.e.d6_user_picture_file) actually contains the correct process plugins to generate the correct D8 URI, butMigration::transform()filters out those process plugins, because it only performs those pertaining to the destination ID properties andEntityFiledoes not declareurias an ID. - That is why the patch adds the
uriproperty as an ID. With that the migration actually succeeds and users are migrated. - The actual file entities for the user pictures are also migrated, albeit not yet correctly: The
uriis processed with the\Drupal\migrate_drupal\Plugin\migrate\process\d6\FileUri. However, both$file_directory_pathand$is_publicare empty inFileUri::transform()so that the directory path does not get removed correctly and theprivatescheme is used instead ofpublic.
At this point I would really like some info on what the heck is going on here and if my debugging efforts make even the slightest sense from a Migration expert's perspective before trying to make those properties work as well.
Proposed resolution
???
Remaining tasks
User interface changes
API changes
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | migrate_upgrade-picture-migration-fix-2336281-7.patch | 689 bytes | nicoloye |
| d6-user-picture-migration-fix.patch | 2.32 KB | tstoeckler |
Comments
Comment #1
benjy commentedI didn't fully ready through the issue summary but can you first try with this patch: #2244555: Use copy() directly instead of file_unmanaged_copy().
It's a known issue that file migrations won't work at all without first applying that core patch.
Comment #2
tstoecklerAhh thanks for the pointer. Will try that!
Comment #3
tstoecklerSo that issue introduces a
MigrateExceptionif thefile_prepare_directory()call fails. That makes the migrate system properly skip that row, so that the migration can at least proceed. With that I can at least complete migrations which depend on this one - even though the user pictures are not migrated. The issues described here are still valid though: Both$sourceis an empty string and$destinationisNULLeven with the patch applied.Comment #4
ultimikeComment #5
nixou commentedHi, this message just to say that we are actually working on this problem at Drupal Dev Days.
We will update this thread if we have some informations to help.
Comment #6
nicoloye commentedThis patch for migrate_upgrade module should do the trick for the backoffice part.
Done together with @Nixou on drupal dev days.
Also if you need to test such migration through drush and a manifest file. Add those options to your file (trailing slash is important !)
Comment #8
nicoloye commentedAs the patch doesn't concern the core we moved it on the module issues here : https://www.drupal.org/node/2471138
Comment #10
benjy commented@tstoeckler can you confirm you were using the UI when testing this? If that's the case, we should have just moved this issue into the Migrate Upgrade issue queue.
Comment #11
mikeryanThis was a contrib issue, long since addressed in the duplicate issue #2471138: User's picture are not imported.