Problem/Motivation

Similar to #3096951: d7_node migration should have dependency on d7_node_title_label migration and #3097327: d7_node_title_label migration plugin incorrectly generating base_field_override for every node type, even those that don't have an overridden title label.

Right now there is only one:

  • "View Modes" (d7_view_modes) migration
  • "Field configuration" (d7_field) migration
  • "Field instance configuration" (d7_field_instance) migration
  • "Field formatter configuration" (d7_field_formatter_settings) migration
  • "Field instance widget configuration" (d7_field_instance_widget_settings) migration

… rather than one of those per entity type + bundle.

This is harder to understand, and harder to debug.

Furthermore, just like #3097314: d7_comment migration should have dependency on d7_comment_entity_display, same for d7_custom_block + block_content_entity_display, the concrete entity migration not having a dependency on the above configuration makes it harder to compare the data on the destination D8 site with the source D7 site, because equivalent formatters and widgets will be used.

Proposed resolution

  • Add a deriver to each of the aforementioned migration plugins.
  • Add optional migration dependencies. to the corresponding content entity migrations.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

CommentFileSizeAuthor
#92 core-derived_field_and_field_display_migrations-3097336-92-10.2.0.patch88.1 KBwim leers
#91 core-derived_field_and_field_display_migrations-3097336-91-10.2.0.patch89.59 KBwim leers
#90 core-derived_field_and_field_display_migrations-3097336-90--compatible-with-3202462-20.patch92.95 KBwim leers
#88 interdiff-3097336-85-88.txt876 bytesyash.rode
#88 core-derived_field_and_field_display_migrations-3097336-88--compatible-with-3202462-6.patch93.71 KByash.rode
#86 interdiff-3097336-85-86.txt930 bytesyash.rode
#86 core-derived_field_and_field_display_migrations-3097336-86--compatible-with-3202462-6.patch93.77 KByash.rode
#85 core-derived_field_and_field_display_migrations-3097336-85--compatible-with-3202462-6.patch89.18 KBwim leers
#84 core-derived_field_and_field_display_migrations-3097336-84--compatible-with-3202462-6.patch89.18 KBwim leers
#83 core-derived_field_and_field_display_migrations-3097336-83--compatible-with-3202462-6.patch89.17 KBhuzooka
#82 core-derived_field_and_field_display_migrations-3097336-82.patch89.29 KBwim leers
#82 interdiff.txt525 byteswim leers
#81 core-derived_field_and_field_display_migrations-3097336-80.patch89.71 KBwim leers
#81 interdiff.txt5.37 KBwim leers
#81 interdiff-due-to-omitted-patches.txt1.77 KBwim leers
#78 interdiff-3097336-77-78.txt4.37 KBhuzooka
#78 core-derived_field_and_field_display_migrations-3097336-78.patch94.45 KBhuzooka
#77 interdiff-3097336-75-77.txt2.98 KBhuzooka
#77 core-derived_field_and_field_display_migrations-3097336-77.patch94.62 KBhuzooka
#75 3097336-75.patch91.07 KBwim leers
#75 interdiff.txt1.61 KBwim leers
#73 proposed-nit-fixes.txt3.98 KBwim leers
#72 interdiff-3097336-69-72.txt3.71 KBhuzooka
#72 core-derived_field_and_field_display_migrations-3097336-72.patch90.21 KBhuzooka
#69 interdiff-3097336-68-69.txt2.65 KBhuzooka
#69 core-derived_field_and_field_display_migrations-3097336-69.patch91.47 KBhuzooka
#68 interdiff-3097336-67-68.txt77.06 KBhuzooka
#68 core-derived_field_and_field_display_migrations-3097336-68.patch94.12 KBhuzooka
#67 core-derived_field_and_field_display_migrations-3097336-67.patch58.46 KBhuzooka
#2 3097336-2-do-not-test.patch8.89 KBwim leers
#6 3097336-6-do-not-test.patch5.06 KBgabesullice
#6 interdiff-2-6.txt11.34 KBgabesullice
#8 3097336-8-do-not-test.patch10.47 KBgabesullice
#9 interdiff.txt8.49 KBgabesullice
#9 3097336-9-do-not-test.patch15.1 KBgabesullice
#10 interdiff-9-10.patch5.43 KBgabesullice
#10 3097336-10-do-not-test.patch15.15 KBgabesullice
#11 interdiff-10-11.txt2.64 KBgabesullice
#11 3097336-11-do-not-test.patch16.26 KBgabesullice
#26 3097336-26-do-not-test.patch16.6 KBwim leers
#27 interdiff.txt907 byteswim leers
#27 3097336-27-do-not-test.patch16.66 KBwim leers
#28 interdiff.txt766 byteswim leers
#28 3097336-28-do-not-test.patch16.66 KBwim leers
#29 interdiff.txt6.3 KBwim leers
#29 3097336-29-do-not-test.patch19.92 KBwim leers
#30 interdiff.txt6.72 KBwim leers
#30 3097336-30-do-not-test.patch25.52 KBwim leers
#34 interdiff-3097336-30-34.txt23.77 KBhuzooka
#35 core-derived_field_and_field_display_migrations-3097336-34--do-not-test.patch36.83 KBhuzooka
#36 core-derived_field_and_field_display_migrations-3097336-36--do-not-test.patch147.57 KBhuzooka
#36 interdiff-3097336-34-36.txt2.24 KBhuzooka
#37 core-derived_field_and_field_display_migrations-3097336-37--chained--do-not-test.patch36.28 KBhuzooka
#38 core-derived_field_and_field_display_migrations-3097336-38--chained--do-not-test.patch40.12 KBhuzooka
#38 interdiff-3097336-37-38.txt10.45 KBhuzooka
#40 core-derived_field_and_field_display_migrations-3097336-40--chained--do-not-test.patch40.39 KBhuzooka
#40 interdiff-3097336-38-40.txt2.91 KBhuzooka
#42 core-derived_field_and_field_display_migrations-3097336-42--chained--do-not-test.patch49.88 KBhuzooka
#42 interdiff-3097336-40-42.txt14.22 KBhuzooka
#43 core-derived_field_and_field_display_migrations-3097336-43--chained--do-not-test.patch50.81 KBhuzooka
#43 interdiff-3097336-42-43.txt2.24 KBhuzooka
#44 interdiff-3097336-43-44.txt3.9 KBhuzooka
#44 core-derived_field_and_field_display_migrations-3097336-44--chained--do-not-test.patch51.7 KBhuzooka
#46 interdiff-3097336-44-46.txt8.01 KBhuzooka
#46 core-derived_field_and_field_display_migrations-3097336-46---chained--do-not-test.patch54.33 KBhuzooka
#52 core-derived_field_and_field_display_migrations-3097336-52---chained--do-not-test.patch2.03 MBhuzooka
#52 interdiff-3097336-46-52.txt2.32 KBhuzooka
#53 core-derived_field_and_field_display_migrations-3097336-53---chained--do-not-test.patch56.18 KBhuzooka
#53 interdiff-3097336-46-53.txt2.32 KBhuzooka
#54 core-derived_field_and_field_display_migrations-3097336-54--chained--do-not-test.patch57.68 KBhuzooka
#54 interdiff-3097336-46-54.txt3.83 KBhuzooka
#55 core-derived_field_and_field_display_migrations-3097336-55--chained--do-not-test.patch58.78 KBhuzooka
#55 interdiff-3097336-54-55.patch2.96 KBhuzooka
#57 core-derived_field_and_field_display_migrations-3097336-57--chained--do-not-test.patch58.79 KBhuzooka
#57 interdiff-3097336-55-57.txt1.38 KBhuzooka
#60 interdiff.txt2.27 KBwim leers
#60 core-derived_field_and_field_display_migrations-3097336-60--chained--do-not-test.patch59.94 KBwim leers
#62 core-derived_field_and_field_display_migrations-3097336-62--chained--do-not-test.patch58.66 KBhuzooka
#62 interdiff-3097336-60-62.txt14.42 KBhuzooka

Comments

Wim Leers created an issue. See original summary.

wim leers’s picture

Status: Active » Needs review
StatusFileSize
new8.89 KB

Not fully working yet, but this gets us pretty far along the way :)

wim leers’s picture

+++ b/core/modules/node/src/Plugin/migrate/D7FieldInstanceWidgetConfigurationDeriver.php
@@ -0,0 +1,128 @@
+      // @todo make this work not just for the `node` entity type but also `comment` etc.
+      $entity_type_id = 'node';

This is by far the biggest TODO. Right now, this only is able to generate derivatives per Node bundle. It can't do it yet for other entity types.

I think a viable strategy here is to create a derivative per node type (Node bundle), but for all other entity types, create one derivative per entity type.

quietone’s picture

I've looked at this over the past days (while on holiday) and every time I am not convinced this is needed. I am happy to be wrong about that and maybe I still have blinders on because of #2208401: [META] Remaining multilingual migration paths.

webchick’s picture

Speaking from a user/developer experience POV, I like it because it allows me to divide my migration pain into more manageable chunks.

If I were to migrate Drupal.org to D8, for example, we have, let's see...

- ~85,500,000 nodes
- ~8,000,000 comments (and that's just the published ones :P)
- ~2,000,000 users

...and so on.

That's an extreme example. :) But even in my crappy D7 blog, this would allow me to focus on one or two smaller areas of the migration (e.g. custom blocks, or pages, for which I only have a few) prior to getting into the stuff with more hard-core dependencies that need thought/work (e.g. a couple blog posts have the PHP filter, oh noes), and still experience early "hey things are happening!" success.

gabesullice’s picture

StatusFileSize
new5.06 KB
new11.34 KB

Refined the patch in #2 so that it will be easily used for other entity types and bundles. I think I lost some of the work to establish proper dependencies that was in #2. I'll restore that tomorrow.

wim leers’s picture

gabesullice’s picture

StatusFileSize
new10.47 KB

Okay, this now breaks the field configuration migration out into separate migrations per entity type and sets up the appropriate dependencies for nodes, terms and field instances.

Next up: views modes, field formatter and field widget configurations.

gabesullice’s picture

StatusFileSize
new8.49 KB
new15.1 KB

Alright this patch completes the derivation of all migrations listed in the issue summary, it also adds the d7_view_modes, d7_field_formatter_settings, and d7_field_instance_widget_settings migrations as optional dependencies of the d7_node and d7_comment migrations as this information was previously missing.

gabesullice’s picture

StatusFileSize
new5.43 KB
new15.15 KB

This should clean up some undefined index errors and a copy pasta problem with an assert that was mucking up the watchdog logs.

I think there are still some weird dependency things going one where certain derived node migrations are depending on all of the derived view mode migrations instead of just depending on the ones that it "cares" about.

gabesullice’s picture

StatusFileSize
new2.64 KB
new16.26 KB

Fixes the view mode thing.

heddn’s picture

I'm not sure that replicating like rabbits the various derivers helps anything in core. If someone wanted to add this in contrib (migrate_upgrade???) and incubate it there for a while, there might be some benefit. But doing this in core for core's sake wouldn't really help much at this point.

quietone’s picture

Yes, that is what has been bothering me about this work, that is, core does not need this. So let's move it to contrib and keep this valuable work. I have no suggestion for where to put it and mgrate_upgrade is definitely a possibility. I would like to mention that there is an issue to move migrate_upgrade to drush itself #2709537: Move Drush commands into Drush itself. Maybe that will influence the decision?

wim leers’s picture

@heddn & @quietone: I think we heard you loud and clear. Thanks for your patience, your guidance, and your thoughtful feedback! Much appreciated 😊

So, this then becomes a question about which contrib module to move it into. migrate_upgrade doesn't really make sense to me, because it's 100% about Drush. This is absolutely independent of Drush.

To @quietone's point: #2709537: Move Drush commands into Drush itself and the sibling issue https://github.com/drush-ops/drush/issues/2140 were opened in 2016. Drush maintainers said "sure, if it comes with tests and a maintainer". I don't think that's suddenly going to happen?

alison’s picture

So, migrate_plus?

heddn’s picture

All things related to upgrading from a previous version of drupal, without regard to if that means drush or web ui or whatever should really land in migrate upgrade. So while drush is the only mechanism in migrate upgrade, that doesn't mean someone could add a web ui.

wim leers’s picture

Aha! That is really good to know!

So then the question becomes: as a maintainer of Migrate Upgrade, would you accept this patch in Migrate Upgrade?

heddn’s picture

Yes.

Implementation details... we'd want to have an additional flag to the drush command to use this option. Or maybe an option to turn it off. Some way to flag it.

wim leers’s picture

But … would it be a thing that only works for the drush command? I imagined it'd be a hook_migration_plugins_alter() implementation in migrate_upgrade?

heddn’s picture

It would work however we wanted it to work. There could be a state flag or something. It could be developed initially for drush but later made available for a web ui. 🤷‍♂️

damienmckenna’s picture

Do this and the similar issues need change notices?

mikelutz’s picture

Status: Needs review » Needs work
Issue tags: -Needs tests +Needs followup

I would like to close this, but I'm setting to nw because it needs a follow up issue filed in migrate upgrade. Once that is done, this should be closed won't fix and the new issue linked.

heddn’s picture

Status: Needs work » Needs review

Alternatively, you can just move tickets from one project queue to another without closing them.

quietone’s picture

Project: Drupal core » Migrate Upgrade
Version: 8.9.x-dev » 8.x-3.x-dev
Component: migration system » Code
Status: Needs review » Needs work
Issue tags: -Needs followup

I prefer the alternative and will take the action to move this to Migrate Upgrade.

wim leers’s picture

+1 for moving — that way we don't lose the comment history :)

wim leers’s picture

StatusFileSize
new16.6 KB
wim leers’s picture

StatusFileSize
new907 bytes
new16.66 KB

Fix lots of notices.

wim leers’s picture

StatusFileSize
new766 bytes
new16.66 KB

Fixed another notice.

wim leers’s picture

StatusFileSize
new6.3 KB
new19.92 KB

If optional migration dependencies include both:

  • "optional" dependencies just for optimal ordering (truly optional)
  • as well as "optional" dependencies that are essential for the data model (not really optional)

… then it's impossible to deduce which configuration must be migrated prior to being able to migrate + view those entities immediately after running the migration.

So… this makes many more migration dependencies required. Which in turn triggered the need for a change in \Drupal\migrate\Plugin\Migration::checkRequirements() — I've left a detailed comment explaining the rationale.

Ideally, we'd have a way to know which migrations are necessary for the migration of entities of a certain entity type + bundle. Then we would have an alternative way to deciding the combinations of migrations to run together for it to make sense to a site builder. That's a much bigger conversation to have, and at least this helps to keep the conversation going.

wim leers’s picture

StatusFileSize
new6.72 KB
new25.52 KB
wim leers’s picture

Still to do: the equivalent of #30 for node_type, comment_type, and more. Ideally we do this in a generic way 🤞

huzooka’s picture

Assigned: Unassigned » huzooka
huzooka’s picture

huzooka’s picture

StatusFileSize
new23.77 KB

Taxonomy term (and user) derivatives should be fine.

Still @TODO: node_type, comment_type.

huzooka’s picture

Adding the missing WIP patch (still on top of core + the patches from #33).

huzooka’s picture

This patch fixes the taxonomy vocabulary migrate source plugin issue we have in #35, and a regression of the comment migrations.

huzooka’s picture

huzooka’s picture

Drupal 7 node type migrations are derivered migrations.

huzooka’s picture

  1. +++ b/core/modules/field/src/Plugin/migrate/D7FieldConfigurationMigrationDeriver.php
    @@ -19,13 +21,31 @@ final class D7FieldConfigurationMigrationDeriver extends DeriverBase {
    +
    +    try {
    +      $source->checkRequirements();
    +    }
    +    catch (RequirementsException $e) {
    +      // If the source plugin requirements failed, that means we do not have a
    +      // Drupal source database configured - there is nothing to generate.
    +      return $this->derivatives;
    +    }
    +
    
    +++ b/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
    @@ -19,15 +21,33 @@ class D7FieldInstanceMigrationDeriver extends DeriverBase {
    +
    +    try {
    +      $source->checkRequirements();
    +    }
    +    catch (RequirementsException $e) {
    +      // If the source plugin requirements failed, that means we do not have a
    +      // Drupal source database configured - there is nothing to generate.
    +      return $this->derivatives;
    +    }
    +
    

    These try / catch blocks are really important: without these, if we don't have any fields to migrate, we would see exceptions instead of our Drupal site 😶.

  2. +++ b/core/modules/node/migrations/d7_node_type.yml
    @@ -3,6 +3,7 @@ label: Node type configuration
    +deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
    
    +++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
    @@ -74,24 +74,31 @@ public function getDerivativeDefinitions($base_plugin_definition) {
     
    -    $node_types = static::getSourcePlugin('d7_node_type');
    +    $source_plugin = $this->getSourcePlugin($base_plugin_definition['source']['plugin']);
         try {
    -      $node_types->checkRequirements();
    +      $source_plugin->checkRequirements();
         }
    

    Since D7NodeDeriver almost fulfilled my needs (explode the d7_node_type migration to derived migrations), I modified this class instead of adding a new one.

  3. +++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
    @@ -115,26 +122,40 @@ public function getDerivativeDefinitions($base_plugin_definition) {
    -          $values['migration_dependencies']['required'][$node_title_dep_index] .= ":$node_type";
    ...
    +            if ($dependency_index !== FALSE) {
    +              $values['migration_dependencies']['required'][$dependency_index] .= ":$node_type";
    +            }
    ...
    -          foreach ($base_migration_ids as $base_migration_id) {
    -            $dependency_index = array_search($base_migration_id, $values['migration_dependencies']['required']);
    -            $values['migration_dependencies']['required'][$dependency_index] .= ":node:$node_type";
    +          foreach ($type_and_bundle_migration_derivers as $migration_id) {
    +            $dependency_index = array_search($migration_id, $values['migration_dependencies']['required']);
    +            if ($dependency_index !== FALSE) {
    +              $values['migration_dependencies']['required'][$dependency_index] .= ":node:$node_type";
    +            }
    ...
    -          foreach ($base_migration_ids as $base_migration_id) {
    -            $dependency_index = array_search($base_migration_id, $values['migration_dependencies']['required']);
    -            $values['migration_dependencies']['required'][$dependency_index] .= ":node";
    +          foreach ($type_migration_derivers as $migration_id) {
    +            $dependency_index = array_search($migration_id, $values['migration_dependencies']['required']);
    +            if ($dependency_index !== FALSE) {
    +              $values['migration_dependencies']['required'][$dependency_index] .= ":node";
    +            }
    

    These $dependecy_index vars weren't checked before, these are now fixed as well 🙂

huzooka’s picture

huzooka’s picture

+++ b/core/modules/field/src/Plugin/migrate/D7FieldSettingsMigrationDeriver.php
@@ -18,6 +18,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
       $entity_type_suffix = ':' . $derivative['source']['entity_type'];
       $entity_type_and_bundle_suffix = $entity_type_suffix;

@@ -25,10 +26,9 @@ public function getDerivativeDefinitions($base_plugin_definition) {
       if (isset($derivative['migration_dependencies']['required'])) {
-        $required_migration_ids = [
-          $entity_type_suffix => ['d7_view_modes', 'd7_field'],
-          $entity_type_and_bundle_suffix => ['d7_field_instance'],
-        ];
+        $required_migration_ids[$entity_type_suffix][] = 'd7_view_modes';
+        $required_migration_ids[$entity_type_suffix][] = 'd7_field';
+        $required_migration_ids[$entity_type_and_bundle_suffix][] = 'd7_field_instance';
 

This is where I had faulty logic:

For comment derivatives, both $entity_type_suffix and $entity_type_and_bundle_suffix was :comment, and so this class checked only d7_field_instance for comment:

$required_migration_ids was

[
  ':comment' => [
    'd7_field_instance',
  ],
]

instead of

[
  ':comment' => [
    'd7_view_modes',
    'd7_field',
    'd7_field_instance',
  ],
]
huzooka’s picture

huzooka’s picture

huzooka’s picture

wim leers’s picture

huzooka’s picture

heddn’s picture

I'm torn w/ this issue. I can see some (small?) benefit for it for custom migrations. There's obviously interest in seeing it move along too. But from my personal experience, I don't quite get the large DX that others seem to find in splitting these things up. I'm willing to take and commit anything that the community wants if things like tests, etc are present. But right now I'm struggling w/ understanding why this is needed.

I think that's also why this is in contrib land at the moment too. Which means that we are stuck w/ nasty migration_plugin_alters, which I really don't like as they are hard to maintain for the long term. What are the names of the resulting migration yml files that get spit out when this patch is applied? I'm mainly interested in the field config migrations, rather then the other more content related migrations.

xjm’s picture

FWIW the dependency mapping and data integrity use cases of this seem really valuable to me, although I totally understand the concerns about maintenance burden.

wim leers’s picture

I don't quite get the large DX that others seem to find in splitting these things up.

The improved DX was described by @webchick in #5:

Speaking from a user/developer experience POV, I like it because it allows me to divide my migration pain into more manageable chunks.

If I were to migrate Drupal.org to D8, for example, we have, let's see...

- ~85,500,000 nodes
- ~8,000,000 comments (and that's just the published ones :P)
- ~2,000,000 users

...and so on.

That's an extreme example. :) But even in my crappy D7 blog, this would allow me to focus on one or two smaller areas of the migration (e.g. custom blocks, or pages, for which I only have a few) prior to getting into the stuff with more hard-core dependencies that need thought/work (e.g. a couple blog posts have the PHP filter, oh noes), and still experience early "hey things are happening!" success.

(We discussed this at length in Migration meetings in Slack before.)

heddn’s picture

re #48: I'm hopefully not playing dumb, that isn't my intention. What data integrity issues? I don't see it mentioned anywhere in this issue. Data dependency between related migrations is usually handled successfully by the migrate_lookup plugin. If there are specific cases where we have issues, we typically fix those as we find them.

re #49: There's already 150+ migration templates. If we add more derivers, we'd be looking at many more. There's nothing in the existing API that stops a site from handling these scenarios (via custom migrations) and adding more per bundle or entity type migration templates. But for the smaller sites, less can be more. I am worried that adding more derivatives, we'd be making it more complicated.

Additionally, in real life migrations the config set of migrations get run pretty rarely. A site might use the config generated migrations to build out the new site with the basic config structure. But then site builders start swapping out field collections for custom field types (or paragraphs) and combining content types, etc. Basically, lots of config changes. And at that point, you can't run the config migrations any more. You can only run the content migrations.

From the IS, we're looking at almost (maybe exclusively?) config migrations. So, I state again, I'm torn. I'm happy to go with a larger majority here, but I'm still not fully convinced in the benefit.

quietone’s picture

I'm torn w/ this issue.

Yes, I am torn too. I can see why it makes sense from one point of view. One thing about this that may be a problem from some is the increase in the number of tables. I recall reports of sites not being about to upgrade because of a limit on the number of tables they could have.

All up I completely agree with heddn comments and questions.

huzooka’s picture

huzooka’s picture

huzooka’s picture

This patch refines comment-related migrations.

The migration lookup process plugins will check the corresponding d7_comment:node_type and d7_comment_type:node_type</code migrations instead of all the <code>d7_comment and d7_comment_type migrations.

huzooka’s picture

This change adds d7_filter_format as a required migration dependency to every derived d7_field_instance migration that might need it.

wim leers’s picture

#55:

  1. +++ b/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
    @@ -62,14 +62,31 @@ public function getDerivativeDefinitions($base_plugin_definition) {
    -          $kinds[$entity_type][$bundle] = $bundle;
    ...
    +          if ($field_is_text_type && $field_is_formatted) {
    +            $kinds[$entity_type][$bundle] = TRUE;
    +          }
    +          elseif (!isset($kinds[$entity_type][$bundle])) {
    +            $kinds[$entity_type][$bundle] = FALSE;
    +          }
    
    @@ -81,7 +98,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
    -      foreach ($bundles as $bundle) {
    +      foreach ($bundles as $bundle => $needs_filter) {
    

    Elegant :) 👍

  2. +++ b/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
    @@ -62,14 +62,31 @@ public function getDerivativeDefinitions($base_plugin_definition) {
    +          $field_is_text_type = in_array($row->type, $text_field_types);
    

    Let's use in_array(…, …, TRUE) 🤓

  3. +++ b/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
    @@ -96,6 +113,14 @@ public function getDerivativeDefinitions($base_plugin_definition) {
    +        // Add field formatter migration dependency.
    

    I think this should be:

    // Add dependency on d7_filter_format migration.
    
huzooka’s picture

shaktik’s picture

Status: Needs work » Needs review

@huzooka

It's good to un-assign the issue.

huzooka’s picture

Assigned: huzooka » Unassigned

@shaktik, thanks for reminding me, you're right!

wim leers’s picture

+++ b/core/modules/comment/src/Plugin/migrate/D7CommentDeriver.php
@@ -28,19 +28,34 @@ public function getDerivativeDefinitions($base_plugin_definition) {
+      if (array_values($node_types_sorted) !== array_values($node_comment_fields_sorted)) {
+        throw new \LogicException(sprintf("Source database '%s' seems to be corrupted: node comment field and node type structure do not match each other.", $db->getConnectionOptions()['database']));
+      }

This was introduced in #43.

This is great. But it's:
- more strict than necessary: it could be more forgiving
- less informative than it could be

This improves that.

huzooka’s picture

Re #60:

I deeply agree, I think this is the right approach!

huzooka’s picture

Fixed bugs:

  1. +++ b/core/modules/comment/src/Plugin/migrate/D7CommentDeriver.php
    @@ -42,7 +42,6 @@ class D7CommentDeriver extends DeriverBase {
           $node_comment_fields_statement = $db->select('field_config_instance', 'fci')
             ->fields('fci', ['bundle'])
             ->condition('fci.entity_type', 'comment')
    -        ->orderBy('fci.bundle')
             ->execute();
           $node_comment_fields_sorted = array_reduce($node_comment_fields_statement->fetchAllAssoc('bundle'), function ($ctypes, $item) {
             $node_type_from_ctype = preg_replace('/^comment_node_(.+)/', '${1}', $item->bundle);
    @@ -50,6 +49,7 @@ class D7CommentDeriver extends DeriverBase {
    
    @@ -50,6 +49,7 @@ class D7CommentDeriver extends DeriverBase {
             return $ctypes;
           }, []);
     
    +      sort($node_comment_fields_sorted);
           $node_types_sorted = array_keys($node_types);
           sort($node_types_sorted);
           if (array_values($node_types_sorted) !== array_values($node_comment_fields_sorted)) {
    

    We should sort both of the query results before a strict comparison.

  2. +++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
    @@ -94,9 +94,9 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
           foreach ($node_types as $node_type => $label) {
    -        $is_node_migration = in_array($base_plugin_definition['id'], ['d7_node', 'd7_node_complete', 'd7_node_revision', 'd7_node_translation']);
    -        $is_comment_config_migration = strpos($base_plugin_definition['id'], 'd7_comment_') === 0;
             $values = $base_plugin_definition;
    +        $is_node_migration = $this->getDestinationEntityTypeId($values) === 'node';
    +        $is_comment_config_migration = strpos($values['id'], 'd7_comment_') === 0;
             $values += ['migration_dependencies' => []];
    
    @@ -177,7 +177,7 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
    -        if (!$is_comment_config_migration) {
    +        if ($is_node_migration) {
               /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
               $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values);
               $this->fieldDiscovery->addBundleFieldProcesses($migration, 'node', $node_type);
    

    This change makes node bundle field processes to be added only to node entity migrations.

  3. Every other change reverts a previous "new" (but bad) behavior: the patch in #00 or #60 skipped the creation of field and view mode migrations when the source entity type ID wasn't available on the destination site.

    Previously I thought this was a neat solution, but since the source entity type ID does not necessarily match the new one (e.g. field_collection_item is mapped to paragraph in #2911244: Field collections deriver and base migration), we cannot make such a decision until all migrations have been collected and altered.

wim leers’s picture

Status: Needs review » Needs work

This still generates d7_comment_*:* derivatives for every node type even if the D7 source site does not have the Comment module installed.

It also means that all this configuration is created even though it should not get created!

Solution:

diff --git a/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
index 2aeded1517..f5666e2d68 100644
--- a/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
+++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
@@ -84,6 +84,27 @@ public function getDerivativeDefinitions($base_plugin_definition) {
       return $this->derivatives;
     }
 
+    try {
+      $enabled_modules_results = $source_plugin->getDatabase()
+        ->select('system', 's')
+        ->fields('s', ['name'])
+        ->condition('type', 'module')
+        ->condition('status', 1)
+        ->execute();
+      $enabled_modules = array_keys($enabled_modules_results->fetchAllAssoc('name'));
+    }
+    catch (DatabaseExceptionWrapper $e) {
+      // The system table might not exist for example in tests – nothing to
+      // generate.
+      return $this->derivatives;
+    }
+
+    // If the comment module is not enabled on the source site and we're
+    // deriving a comment migration plugin, refuse to generate anything.
+    if (!in_array('comment', $enabled_modules, TRUE) && strpos($base_plugin_definition['id'], 'd7_comment_') === 0) {
+      return $this->derivatives;
+    }
+
     try {
       $statement = $source_plugin->getDatabase()->select('node_type', 'nt')
         ->fields('nt', ['type', 'name'])
huzooka’s picture

This issue happens even without this patch, because the d7_comment_type migration plugin uses the d7_node_type migration source plugin.

The solution is to create a separate source plugin for comment bundle migration that extends d7_node_type, but with a source_module annotation set to comment.

wim leers’s picture

This still needs to update the d7_book dependency on d7_node to be derived. We can't hardcode it to d7_node:book; we need to derive it for each of the values in the book_allowed_types variable in D7.

huzooka’s picture

This new patch contains a lot of cleanup.
Short update:

  • node and comment migration deriver classes are now separated – lot of logic is removed from D7NodeDeriver and merged into D7CommentDeriver
  • Further config migrations (d7_field_option_translation, d7_field_instance_option_translation.yml and d7_field_instance_label_description_translation.yml) are derived per entity type and bundle
  • Content entity translation are derived per bundle

#66 is unaddressed, but imho it merit to get a standalone issue...

huzooka’s picture

huzooka’s picture

  1. +++ b/core/modules/content_translation/migrations/d7_node_entity_translation.yml
    @@ -5,7 +5,7 @@ migration_tags:
       - translation
       - Content
       - Multilingual
    -deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
    ...
     source:
       plugin: d7_node_entity_translation
     process:
    

    Drupal\content_translation\Plugin\migrate\D7NodeDeriver this this deriver does not exists – this should be Drupal\language\Plugin\migrate\D7NodeDeriver (language is the dependency of content_translation).

  2. --- a/core/modules/content_translation/migrations/d7_taxonomy_term_entity_translation.yml
    +++ b/core/modules/content_translation/migrations/d7_taxonomy_term_entity_translation.yml
       - translation
       - Content
       - Multilingual
    -deriver: Drupal\taxonomy\Plugin\migrate\D7TaxonomyTermDeriver
    +deriver: Drupal\content_translation\Plugin\migrate\D7TaxonomyTermDeriver
     source:
    

    This should be moved into a core patch (with the Drupal\content_translation\Plugin\migrate\D7TaxonomyTermDeriver class)

  3. +++ b/core/modules/content_translation/src/Plugin/migrate/source/d7/EntityTranslationSettings.php
    @@ -14,6 +17,17 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
    @@ -35,6 +49,7 @@ class EntityTranslationSettings extends DrupalSqlBase {
    
    @@ -35,6 +49,7 @@ class EntityTranslationSettings extends DrupalSqlBase {
           // which comment type uses entity translation.
           ->condition('name', 'language_content_type_%', 'LIKE');
         $query->condition($condition);
    +
         return $query;
       }
    

    Unnecessary linebreak.

  4. +++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php
    @@ -15,6 +18,21 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
    @@ -26,6 +44,7 @@ class FieldInstance extends DrupalSqlBase {
    
    @@ -26,6 +44,7 @@ class FieldInstance extends DrupalSqlBase {
           ->condition('fc.storage_active', 1)
           ->condition('fc.deleted', 0)
           ->condition('fci.deleted', 0);
    +
         $query->join('field_config', 'fc', 'fci.field_id = fc.id');
    

    Unnecessary linebreak.

  5. +++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldLabelDescriptionTranslation.php
    @@ -14,10 +17,25 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
    @@ -45,7 +63,16 @@ class FieldLabelDescriptionTranslation extends DrupalSqlBase {
    
    @@ -45,7 +63,16 @@ class FieldLabelDescriptionTranslation extends DrupalSqlBase {
         $query->condition($condition);
         $query->innerJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
     
    -    $query->leftjoin('field_config_instance', 'fci', 'fci.bundle = i18n.objectid AND fci.field_name = i18n.type');
    +    // This was a left outer join before, even though "entity_type" and "bundle"
    +    // are required properties. Since this was fixed here, the original
    +    // migration plugin definition could be simplified a lot.
    +    $query->join('field_config_instance', 'fci', 'fci.bundle = i18n.objectid AND fci.field_name = i18n.type');
    +
    +    if ($entity_type && $bundle) {
    +      $query->condition('fci.entity_type', $entity_type)
    +        ->condition('fci.bundle', $bundle);
    +    }
    +
    

    This should be moved into a core patch.

  6. +++ b/core/modules/language/src/Plugin/migrate/source/d7/LanguageContentSettings.php
    @@ -65,4 +85,18 @@ class LanguageContentSettings extends DrupalSqlBase {
    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function checkRequirements() {
    +    parent::checkRequirements();
    +    if (!$this->moduleExists('node')) {
    +      // The source plugin requires the "node_type" database table of the node
    +      // module.
    +      throw new RequirementsException('The node module is not enabled in the source site.', [
    +        'source_module_additional' => 'node',
    +      ]);
    +    }
    +  }
    

    This should be moved into a core patch.

  7. +++ b/core/modules/language/src/Plugin/migrate/source/d7/LanguageContentSettingsTaxonomyVocabulary.php
    @@ -25,6 +25,8 @@ class LanguageContentSettingsTaxonomyVocabulary extends Vocabulary {
    +
    +    $qcr = (clone $query)->execute()->fetchAll();
    

    This should be removed.

huzooka’s picture

New task(s) discovered after 9.1 core update:

I don't really see how these could be derived as well since the major part of the required (code) infrastructure is in a core issue #3051251: Existing menu links show validation issues on migration (and ALL menu links pointing to node translations are invalid).

huzooka’s picture

Addressed #70.1, #70.3, #70.4 and #70.7

wim leers’s picture

StatusFileSize
new3.98 KB

👏👏👏👏 Epic work, once again! 🤩

  1. +++ b/core/modules/comment/src/Plugin/migrate/D7CommentDeriver.php
    @@ -28,54 +34,15 @@ class D7CommentDeriver extends DeriverBase {
    -      $db = $source_plugin->getDatabase();
    

    👍 Significant changes here, but all for the better. A huge method refactored to be smaller, more readable, and more maintainable — in particular thanks to the introduction of \Drupal\comment\Plugin\migrate\D7CommentDeriver::processPluginDefinition() and \Drupal\comment\Plugin\migrate\D7CommentDeriver::updateCommentMigrationLookups().

  2. +++ b/core/modules/comment/src/Plugin/migrate/D7CommentDeriver.php
    @@ -28,54 +34,15 @@ class D7CommentDeriver extends DeriverBase {
    +        $b_id = $base_plugin_definition['id'];
    

    Debug leftover 🤓

  3. +++ b/core/modules/comment/src/Plugin/migrate/D7CommentDeriver.php
    @@ -84,6 +51,7 @@ class D7CommentDeriver extends DeriverBase {
    +          'd7_comment',
    

    👍 This is not because d7_comment wasn't already derived; this is because now for the first time there are migration plugins dependingon d7_comment:<bundle> — specifically d7_comment_entity_translation.

  4. +++ b/core/modules/comment/src/Plugin/migrate/D7CommentDeriver.php
    @@ -103,97 +74,180 @@ class D7CommentDeriver extends DeriverBase {
    +   * @param CommentType $comment_type_source
    

    🤓 Needs FQCN.

  5. +++ b/core/modules/comment/src/Plugin/migrate/source/CommentType.php
    @@ -16,12 +19,28 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
    +    if ($node_type = $this->configuration['node_type']) {
    +      $query->condition('t.type',$node_type);
    +    }
    

    👍 I didn't realize we didn't already have this! 😳

    Now this is consistent with \Drupal\comment\Plugin\migrate\source\d7\Comment.

  6. +++ b/core/modules/comment/src/Plugin/migrate/source/d7/Comment.php
    @@ -15,21 +19,31 @@ use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
    +    $query->join($node_query, 's', 'c.nid = s.nid');
    +    $query->addField('s', 'type', 'node_type');
    

    👍 It took me a moment to understand this s — but I get it now: it's the "table alias" for the subquery (which is a virtual/ephemeral table).

  7. +++ b/core/modules/comment/src/Plugin/migrate/source/d7/Comment.php
    @@ -104,4 +118,15 @@ class Comment extends FieldableEntity {
    +  public function checkRequirements() {
    +    if (!$this->moduleExists('node')) {
    +      // Node module is a requirement.
    +      throw new RequirementsException('Node module is not enabled on source site');
    +    }
    +    parent::checkRequirements();
    +  }
    

    👍

  8. +++ b/core/modules/comment/src/Plugin/migrate/source/d7/CommentEntityTranslation.php
    @@ -31,6 +31,9 @@ class CommentEntityTranslation extends FieldableEntity {
    +    if ($node_type = $this->configuration['node_type'] ?? NULL) {
    +      $query->condition('n.type', $node_type);
    +    }
    

    👍

    🤔 Just one Q: why the $config['key'] ?? NULL pattern here whereas everywhere else you updated the constructor to generate a default configuration key-value pair, to ensure it is set?

  9. +++ b/core/modules/config_translation/migrations/d7_field_instance_label_description_translation.yml
    @@ -4,6 +4,7 @@ migration_tags:
    +deriver: Drupal\config_translation\Plugin\migrate\D7FieldInstanceMigrationDeriver
     class: Drupal\migrate_drupal\Plugin\migrate\FieldMigration
     field_plugin_method: alterFieldInstanceMigration
     source:
    @@ -56,7 +57,3 @@ destination:
    
    @@ -56,7 +57,3 @@ destination:
     migration_dependencies:
       required:
         - d7_field_instance
    -  optional:
    -    - d7_node_type
    -    - d7_comment_type
    -    - d7_taxonomy_vocabulary
    

    👍 Rather than nonsensical broad optional dependencies, the deriver will add only the relevant dependencies while deriving definitions!

  10. +++ b/core/modules/config_translation/migrations/d7_field_instance_option_translation.yml
    @@ -22,6 +23,7 @@ process:
    +  # TODO ENSURE THIS IS WORKING AS EXPECTED.
    

    👍 This is being fixed in #3187463: Fix "d7_field_option_translation" process plugin. It is working as expected, and was merely a bug in the sample source data.

    🙏 Let's remove this TODO!

  11. +++ b/core/modules/content_translation/migrations/d7_node_entity_translation.yml
    @@ -5,7 +5,7 @@ migration_tags:
    -deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
    +deriver: Drupal\content_translation\Plugin\migrate\D7NodeDeriver
    

    🙈 This does not exist. Already fixed!

  12. +++ b/core/modules/content_translation/src/Plugin/migrate/source/d7/EntityTranslationSettings.php
    @@ -160,6 +175,22 @@ class EntityTranslationSettings extends DrupalSqlBase {
    +    $rows_before = $rows;
    

    🤓 Debug leftover.

  13. +++ b/core/modules/content_translation/src/Plugin/migrate/source/d7/EntityTranslationSettings.php
    @@ -160,6 +175,22 @@ class EntityTranslationSettings extends DrupalSqlBase {
    +    if ($entity_type && $bundle) {
    +      $rows = array_reduce($rows, function (array $carry, array $row) use ($entity_type, $bundle) {
    +        if (
    +          $entity_type === $row['target_entity_type_id'] &&
    +          $bundle ===  $row['target_bundle']
    +        ) {
    +          $carry[] = $row;
    +        }
    +        return $carry;
    +      }, []);
    +    }
    

    This restricts the generated rows to just those of the specified entity type + bundle.

    🤔 But shouldn't it be possible to restrict only to entity_type? User doesn't have a bundle after all. Then this if-test would be wrong!
    Oh, I see that you specified d7_entity_translation_settings:user:user, and tests are passing, so evidently this is working. So: 👍

    🙏 A comment here would be welcome 🤓

  14. +++ b/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
    @@ -34,30 +35,33 @@ class D7FieldInstanceMigrationDeriver extends DeriverBase {
    -      $query = $source->getDatabase()->select('field_config_instance', 'fci')
    -        ->fields('fci')
    -        ->fields('fc', ['type'])
    -        ->condition('fc.active', 1)
    -        ->condition('fc.storage_active', 1)
    -        ->condition('fc.deleted', 0)
    -        ->condition('fci.deleted', 0);
    -      $query->join('field_config', 'fc', 'fci.field_id = fc.id');
    -
    -      $result = $query->execute()->fetchAllAssoc('id');
    -      $entity_bundles = array_reduce($result, function (array $kinds, object $row) {
    -        $entity_type = $row->entity_type;
    -        $bundle = $row->bundle;
    -        $data = unserialize($row->data);
    -        $text_field_types = ['text', 'text_long', 'text_with_summary'];
    -        $field_is_text_type = in_array($row->type, $text_field_types, TRUE);
    -        $field_is_formatted = isset($data['settings']['text_processing']) && (int) $data['settings']['text_processing'] === 1;
    -        if ($field_is_text_type && $field_is_formatted) {
    -          $kinds[$entity_type][$bundle] = TRUE;
    +      $text_field_types = ['text', 'text_long', 'text_with_summary'];
    +      $source_rows = iterator_to_array($source, FALSE);
    

    💯 D'oh, right, this was repeating the query logic from \Drupal\field\Plugin\migrate\source\d7\FieldInstance::query()!

    This is a big improvement wrt brittleness.

    Overall, all changes here are a solid refactor that make this more robust/easier to maintain 👍

  15. +++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldLabelDescriptionTranslation.php
    @@ -45,7 +63,16 @@ class FieldLabelDescriptionTranslation extends DrupalSqlBase {
    +    // This was a left outer join before, even though "entity_type" and "bundle"
    +    // are required properties. Since this was fixed here, the original
    +    // migration plugin definition could be simplified a lot.
    +    $query->join('field_config_instance', 'fci', 'fci.bundle = i18n.objectid AND fci.field_name = i18n.type');
    +
    +    if ($entity_type && $bundle) {
    +      $query->condition('fci.entity_type', $entity_type)
    +        ->condition('fci.bundle', $bundle);
    +    }
    

    🤔 I'm not sure this comment is accurate, given the if-test that follows: that makes it pretty obvious that both are optional configuration for this source plugin?

  16. +++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
    @@ -85,107 +94,122 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
    +          'd7_node',
    +          'd7_node_complete',
    +          'd7_node_type',
    +          'd7_node_title_label',
    +          'd7_comment_type',
    +          'd7_comment_field',
    +          'd7_comment_entity_display',
    +          'd7_comment_entity_form_display',
    +          'd7_comment_entity_form_display_subject',
    +          'd7_comment_field_instance',
    

    👍 The first two are new.

  17. +++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php
    @@ -85,107 +94,122 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
    +        $type_and_bundle_migration_derivers = [
    +          'd7_field_instance',
    +          'd7_field_formatter_settings',
    +          'd7_field_instance_widget_settings',
    +          'd7_entity_translation_settings',
    +        ];
    

    👍 This last one is new.

  18. +++ b/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php
    @@ -87,12 +87,16 @@ class D7TaxonomyTermDeriver extends DeriverBase implements ContainerDeriverInter
    +        $aaa_id = $base_plugin_definition['id'];
    

    Definitely debug leftover 😂

  19. +++ b/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php
    @@ -87,12 +87,16 @@ class D7TaxonomyTermDeriver extends DeriverBase implements ContainerDeriverInter
             // // if ($base_plugin_definition['id'] === 'd7_taxonomy_term') {
    

    And this is a pre-existing debug leftover 😂

  20. +++ b/core/modules/taxonomy/src/Plugin/migrate/D7VocabularyDeriver.php
    @@ -31,28 +36,34 @@ class D7VocabularyDeriver extends DeriverBase {
         catch (DatabaseExceptionWrapper $e) {
           // The system table might not exist for example when the
           // MigrationPluginManager gathers up the migration definitions but we do
           // not actually have a Drupal 7 source database.
    -      return $this->derivatives;
    -    }
    

    👍 Ah, yes, this makes more sense… defensive programming FTW!

Nits fixed in attached interdiff.

wim leers’s picture

This would have saved me a lot of time testing this:

 .../field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php       | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php b/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
index f41451310d..733a10e378 100644
--- a/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
+++ b/core/modules/field/src/Plugin/migrate/D7FieldInstanceMigrationDeriver.php
@@ -36,6 +36,9 @@ public function getDerivativeDefinitions($base_plugin_definition) {
 
     try {
       $text_field_types = ['text', 'text_long', 'text_with_summary'];
+      // Derive based on the source rows rather than performing our own queries
+      // here, to ensure the `title` module edge case is respected in
+      // \Drupal\field\Plugin\migrate\source\d7\FieldInstance::query().
       $source_rows = iterator_to_array($source, FALSE);
       $entity_types_and_bundles = array_reduce($source_rows, function (array $carry, Row $row) use ($text_field_types) {
         [
wim leers’s picture

StatusFileSize
new1.61 KB
new91.07 KB

In testing this, I also noticed that d7_taxonomy_vocabulary_translation (which was introduced in #3035392: Migrate vocabulary translations and taxonomy term references for Drupal 7 node translations) was not yet updated to get the necessary derivatives.

huzooka’s picture

Assigned: Unassigned » huzooka

Re #66:

It seems that the book_allowed_types setting does not restrict anything neither in Drupal 7 nor in Drupal 8 or Drupal 9.

Even so, we can refine the migration dependencies of the d7_book migration.

huzooka’s picture

This addresses #76.

Now I'll address #73.

huzooka’s picture

Assigned: huzooka » Unassigned
StatusFileSize
new94.45 KB
new4.37 KB

This patch addresses the review posted in #73 and also adds the comment from #74.

Re #73:

  1. 😀
  2. Removed.
  3. 😀 Yepp, exactly!
  4. Fixed.
  5. 👍
  6. 👍
  7. 😀
  8. I don't want to override the constructor just for setting a single configuration key used only once.
  9. 👍
  10. Removed.
  11. 👍
  12. Removed.
  13. Added a very simple comment.
  14. 👍
  15. Whenever a deriver class instantiates this source plugin, it doesn't want to set entity_type (or bundle) restrictions. So ideally, a source plugin should handle these configs as optional configs.
  16. 👍
  17. 👍
  18. Removed.
  19. And this was also removed.
  20. 👍
wim leers’s picture

Reviewed #78 in detail — no remarks.

Tested #78 with the d7_book migration in a real-world test case. Works well 👍

wim leers’s picture

wim leers’s picture

… and patch 🙈

This reverts 99% of migration_dependencies changes (and #3096951 + #3097314 also modified those in 3 migrations). It touches 6 fewer files overall.

The only two dependencies additions that have not yet been reverted:

diff --git a/core/modules/content_translation/migrations/d7_user_entity_translation.yml b/core/modules/content_translation/migrations/d7_user_entity_translation.yml
index 07a1b4f59c..3844ec920d 100644
--- a/core/modules/content_translation/migrations/d7_user_entity_translation.yml
+++ b/core/modules/content_translation/migrations/d7_user_entity_translation.yml
@@ -23,5 +23,5 @@ destination:
 migration_dependencies:
   required:
     - language
-    - d7_entity_translation_settings
+    - d7_entity_translation_settings:user:user
     - d7_user

and

diff --git a/core/modules/taxonomy/migrations/d7_taxonomy_term.yml b/core/modules/taxonomy/migrations/d7_taxonomy_term.yml
index 1bae2d6e32..281e54bcd2 100644
--- a/core/modules/taxonomy/migrations/d7_taxonomy_term.yml
+++ b/core/modules/taxonomy/migrations/d7_taxonomy_term.yml
@@ -40,5 +40,6 @@ destination:
 migration_dependencies:
   required:
     - d7_taxonomy_vocabulary
+    - d7_field
   optional:
     - d7_field_instance

Removing both should be possible, but have enormous side/ripple effects for downstream code.

In any case, consider this a big leap forward to making this committable and maintainable :)

wim leers’s picture

This reverts the sole addition to core/modules/taxonomy/migrations/d7_taxonomy_term.yml.

huzooka’s picture

wim leers’s picture

wim leers’s picture

yash.rode’s picture

If comment module is not enabled on soure site then we should not migrate d7_field: comment,
Interdiff denotes the actual change and other changes are caused because of the re-roll.

wim leers’s picture

+++ b/core/modules/field/src/Plugin/migrate/D7FieldConfigurationMigrationDeriver.php
@@ -48,7 +48,12 @@ final class D7FieldConfigurationMigrationDeriver extends DeriverBase {
+      if ($entity_type === 'comment' && $comment_module_status === '0') {

We usually prefer strict equality checks, but in this case it's actually safer to not do that, because of per-DB peculiarities.

Let's change the second operand to !$comment_module_status or $comment_module_status == 0. See https://3v4l.org/2kf2W.

yash.rode’s picture

follow up for #87. Modified the second operand so that if comment is not present it won't show a php error.

wim leers’s picture

That works! 👍😄

wim leers’s picture

There was a *.orig hunk in there, left over from previous patch iterations, that shouldn't have been there.