Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
We need an upgrade path from D7 for the core Shortcut module.
Remaining Tasks
Write migrations, with tests, covering the following:
- Shortcut sets and user mappings need to be migrated
- Shortcut links need to be re-associated with menu items migrated in #2382985: Migration Files for Drupal 7 Menu & Menu Entries
- Any variables maintained by Shortcut need to be moved into configuration
Committers, please note: #37 is the correct version of this patch.
Comment | File | Size | Author |
---|---|---|---|
#60 | interdiff.txt | 726 bytes | benjy |
#60 | 2500513-60.patch | 37.14 KB | benjy |
#57 | interdiff.txt | 2.45 KB | benjy |
#57 | 2500513-57.patch | 37.37 KB | benjy |
#56 | interdiff.txt | 8.85 KB | benjy |
Comments
Comment #1
svendecabooterComment #2
svendecabooterHere is a first attempt at creating the Shortcut migration.
What the patch does:
* Migrate D7 shortcut sets to D8 shortcut set entities.
* Migrate D7 shortcut menu links to D8 shortcut entities
* Migrate D7 shortcut_set_user associations to D8 shortcut_set_user
The following tasks defined by the op do not seem relevant:
* #2382985 - shortcut links are regular menu items in D7, but are a link field on the Shortcut entity in D8. So presumably the only followup in that issue is skip migration of the shortcut menus & menu items, since they are no longer relevant in D8.
* There are no variables defined by the D7 Shortcut module
Issues still existing with this patch:
* There should be a dependency on the d7_user migration, but as far as I can tell, this isn't in D8 core yet.
* D8 already provides a "default" shortcut set. We should probably write a special case where the D7 default ("shortcut_set_1") gets migrated to the D8 default set ("default"). Now the D8 default still exists, and the D7 default just becomes another migrated set.
* In Drupal\shortcut\Entity\ShortcutSet::postSave(), the shortcut links from the default set get cloned to any new shortcut set that is created. This behaviour has a result that each migrated shortcut set gets the default D8 shortcut links as well.
* In D7, shortcut links can be enabled / disabled in a shortcut set (via the menu system). In D8 this is no longer possible. In my patch we ignore the hidden shortcut links. To be determined if this is the right behaviour.
* There is no mapping for shortcut_set_users database entries. So no entries get added to {migrate_map_d7_shortcut_set_users}
What still needs to be done:
* Test this patch thoroughly and find solutions for the issues defined above
* Write tests
Any feedback welcome!
Comment #3
svendecabooterComment #4
phenaproximaGo ahead and declare the dependency in the migration; when the patch is ready we'll just postpone this issue on the user migration (if it needs to be postponed -- that one is not far from being ready for commit).
You can achieve this by directly assigning the shortcut set ID. The static_map plugin is your friend :)
Comment #5
phenaproximaComment #6
svendecabooterphenaproxima: thanks for the feedback.
I created a new version of this patch which fixes the following things:
Haven't written lots of D8 tests yet, but I'll dive into that soon.
Comment #7
svendecabooterHere is an updated patch that includes tests for the migrated tables and data.
This patch requires the d7_user migration, and so depends on #2414651: Migration Files for Drupal 7 Users being committed.
With the patch in https://www.drupal.org/node/2414651#comment-10262703 applied, all tests run fine locally.
So testbot will probably fail for now...
Comment #9
svendecabooterComment #10
phenaproximaPostponing on #2414651: Migration Files for Drupal 7 Users.
Comment #11
phenaproximaUnblocked!
Comment #13
svendecabooteryay now it passes :)
Comment #14
phenaproximaWOW! Terrific work @svendecabooter! Very thorough, clear, and easy to follow. I have some changes and fixes to request, but otherwise this is first-class work.
It's preferable here to use the migration process plugin (because having a process plugin named "migration" isn't confusing at all!) to get the ID of the previously migrated shortcut set. Documentation on the migration plugin may be found at https://www.drupal.org/node/2149801
Whoops :) Please add a blank line at the end of the file to satisfy the git gods.
This should also use the migration process plugin to look up the uid from the d7_user migration.
Same here.
Nit: please add a new line between the class declaration and the doc comment.
This doc comment doesn't match the actual argument. :)
IIRC, fields() doesn't apply to destinations, so this can be removed
import() is supposed to return the ID of the saved entity (matching what's declared in getIds()), not a boolean. In this case it should return array($account->id()), and you don't need to check for $account. Because, if you use the migration process plugin to look up the uid (in the d7_shortcut_users migration), a MigrateSkipRowException will be thrown if the user cannot be found, which is an appropriate response in this case.
D'oh. Needs a new line.
Needs source_provider = "shortcut" in the annotation.
Nit: You can return $query directly, no need for a separate return statement.
Needs a new line.
Also needs source_provider = "shortcut" in the annotation.
Same nit: you don't need to return $query separately.
Needs a new line.
Ditto on the source_provider annotation.
Ditto on the return $query nit.
Ditto on the new line. I swear, I'll stop repeating myself now.
This method looks a little light on assertions. I recommend asserting everything you can think of that the migration may have touched. The more assertions we have, the more bugs we will catch.
If there is an OO way to do this, it's preferable. If not, no worries.
Comment #15
phenaproximaChanging status.
Comment #16
svendecabooterI need some help with the 1st issue mentioned by phenaproxima.
I changed the process migration template to use the migration plugin - see updated patch in attachment.
But with only this change, now suddenly shortcut entities don't get migrated anymore.
I'm getting this in Drush:
Fatal error: Call to a member function getFieldStorageDefinition() on a non-object in drupal/core/lib/Drupal/Core/Entity/ContentEntityBase.php on line 1125
It seems the fields and entityKeys are not correctly set when trying to save the Shortcut entity suddenly, but I don't see any feedback as to why that's happening.
I've been debugging for over 2 hours, but can't wrap my head around what's going on exactly...
If anyone has some spare time to try to find the cause of this issue, that would be highly appreciated.
Comment #17
phenaproximaPostponing on #2382985: Migration Files for Drupal 7 Menu & Menu Entries. Shortcut sets and menu links are tightly coupled, so it makes sense to get this done once menu links are migrating OK.
Comment #18
phenaproximaUnblocked!
Comment #19
svendecabooterThe issue mentioned in #16 still seems to exist now that #2382985: Migration Files for Drupal 7 Menu & Menu Entries is in core.
Will have to investigate further what's going on.
Comment #20
svendecabooterHere is an update of the patch with most of the comments by phenaproxima tackled.
Still need to look at 19 - 20 - 21. The rest should be fixed.
With regards to comment #7:
I get the following error when removing the fields() method. It seems the Interface requires this method anyway:
Fatal error: Class Drupal\shortcut\Plugin\migrate\destination\ShortcutSetUsers contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Drupal\migrate\Plugin\MigrateDestinationInterface::fields)
Comment #21
svendecabooterUpdated patch.
#19: I improved the assertions for the ShortcutSet test. Not a lot more I can think of to test, since each ShortcutSet entity only consists of an id and label, and fetches the Shortcut entities with the related id. Not a lot more to it. Shortcut-specific functionality is tested in ShortcutTest.php.
#20: ShortcutSetUsers is not (yet?) an object or entity. See #2446195. Seems there is not a lot of work being done on that, so I just used the function call that is being used by the shortcut module itself.
Only the unit tests left now. Will see if I can squeeze out some more time for that.
Comment #22
svendecabooterAttached the patch with all comments by phenaproxima tackled.
Thanks for reviewing my patch!
Comment #23
svendecabooterNeed to remember those newlines... Updated patch with newlines at the end of the newly added Unit test files
Comment #24
phenaproximaLooks excellent. I have some changes I'd like to see, but I'll take care of these and we'll get this in soon.
We no longer include the "Drupal 6" and "Drupal 7" prefixes in migration labels, so this should just be "Shortcut links".
Nit: This can just be
source: menu_name
.Ditto the label fix here.
This might not be necessary -- it looks like shortcut set IDs are already machine names.
Ix-nay on the "Drupal 7".
Nit: Should be
source: uid
.This stuff might not be entirely necessary, because the uid returned by the lookup in d7_user should be a single value, not an array.
IMO, we should not assign a default value if the user lookup fails; in this case I think it's appropriate to simply skip the row.
It's unclear why we're injecting the database as a dependency; it doesn't seem to be used for anything in the plugin...
It seems to me that we'd want to return the ID as an array containing the set name and user ID (and alter the ids() method to match), since that's really what identifies the imported data, no?
Nit: Let's do fields('ss') instead of cherry-picking.
Ditto.
Let's identify the rows by set_name AND uid, rather than just uid.
It's preferable to pass the shortcut set ID and let assertEntity() load it and assert that it's a ShortcutSetInterface.
Let's not hard-code the number of expected shortcuts in the set -- pass that in as an argument to assertEntity().
This method should probably use the assertEntity() pattern. (The purpose of which is for easier conversion to the data provider pattern that PHPUnit gives us, which we'll probably do in 8.1 or 8.2.)
I'd prefer if you assigned
$this->databaseContents['shortcut_set'] = $this->expectedResults
, rather than repeating the code.Ditto here.
Comment #25
phenaproximaMade the changes I asked for in #24. Let's give this a whirl...
Comment #31
phenaproximaQA is failing patch #25 for no apparent reason -- each time I re-queue it for testing, it fails an update-related test (this patch does not need or introduce any update-related code), for different, random reasons. On @tim.plunkett's advice, setting this issue to NR because DrupalCI passed it.
Comment #36
benjy CreditAttribution: benjy at PreviousNext commentedRTBC, two small things:
I think we always put these in quotes for consistency because when using "@field" it breaks the PECL parser.
80 chars.
Comment #37
svendecabooterPatch with remarks by benjy fixed
Comment #40
phenaproximaDrupalCI has passed patch #37 and @benjy reviewed on IRC this morning. Per #36, RTBC.
Comment #42
webchickAwesome stuff!!
Committed and pushed to 8.0.x. Thanks!
Comment #43
bzrudi71 CreditAttribution: bzrudi71 commentedSeems we broke PostgreSQL bot :( Please see:
https://www.drupal.org/pift-ci-job/34975
Follow up, or should we try to fix it right here?
Comment #44
phenaproximaLet's have a quick-fix follow-up.
Comment #45
phenaproximaFollow-up critical issue filed: #2570265: Migrate test failure on PostgreSQL
Comment #47
catchSorry I'm reverting this instead, this looks like just an ordering issue in the test, but I'd rather not have postgres broke while we review whether that's the case or not.
Comment #48
phenaproximaWith a quick-fix applied, from #2570265: Migrate test failure on PostgreSQL.
Comment #49
benjy CreditAttribution: benjy at PreviousNext commentedSo i refactored the idMap queries to apply the conditions using the key, although the key isn't always set which is why I didn't do it in lookupDestinationId() just yet. This is also an API change for anyone using these functions.
It's a shame #48 had different failures because it would have been nice to commit that as is with the re-order and then handle the ordering issues in a follow-up.
Comment #52
benjy CreditAttribution: benjy at PreviousNext commentedSame approach added for delete. Not done here but deleteDestination() needs refactoring but may have the same issues as lookupDestinationId().
Comment #53
benjy CreditAttribution: benjy at PreviousNext commentedNot looked at the unit tests yet, it's expected they'll still fail.
Comment #56
benjy CreditAttribution: benjy at PreviousNext commentedFixed the delete and the other tests. Still more that I know need fixing but trying get get the Postgres tests to pass.
Comment #57
benjy CreditAttribution: benjy at PreviousNext commentedGetting closer, had to refactor lookupDestinationId() which is trickier because the migration process plugin doesn't have the source id keys currently.
Comment #60
benjy CreditAttribution: benjy at PreviousNext commentedI'm going to split this out into a new issue after this test run.
Comment #61
benjy CreditAttribution: benjy at PreviousNext commentedOpened #2571499: idMap source and destination id filtering requires keys
Comment #62
svendecabooterUnblocked
Comment #63
phenaproxima#2571499: idMap source and destination id filtering requires keys has been committed and it fixes the root of the problem which caused this issue to break PostgreSQL. I have re-tested the original patch (#37) and it now passes PostgreSQL with flying colors -- and everything else, for that matter. Restoring RTBC.
Committers, note that #37 is RTBC!
Comment #64
phenaproximaEr. Restoring RTBC.
Comment #65
webchickOk, let's try that again. :)
Committed and pushed to 8.0.x. Thanks!
Comment #67
webchickComment #69
Wim LeersFollow-up at #3165944: d7_shortcut migration should not have a dependency on d7_menu_links — this introduced an incorrect migration dependency.