Problem/Motivation

The 'date' field plugin for Drupal 6 was replaced with a 'datetime' field plugin that works for both Drupal 6 and 7 migrations. Despite deprecating the original date plugin, the plugin manager still creates an instance of it when requesting a plugin for a D6 date field because it is found first in the plugin list and the annotations say it applies. Removing the type_map from the annotations partially solves this, but due to the fact that the field name and plugin id match, it is still selected to manage D6 date fields even though it shouldn't be anymore.

Due to this, the deprecation error triggered by this plugin was ignored globally, creating technical debt that needs to be resolved for Drupal 9.

Additionally, the same system makes it difficult or impossible for contrib plugin to override a core MigrateField plugin for a specific field. Because the first discovered applicable plugin is used, there is no way to guarantee a contrib plugin will actually override the core plugin.

Proposed resolution

Adding a weight field to the plugin annotation will allow plugins to declare the order in which they should be used for field migrations. Deprecated plugins can be set to a higher weight, and contrib overrides can be set to a lower weight. Applying a sort first by weight, then by plugin ID will assure a single deterministic, testable, and repeatable plugin will be used for any given field and core version.

Remaining tasks

Add a weight field to the MigrateField annotation
Sort the plugins by weight and plugin ID in MigrateFieldPluginManager
Add/refactor/adjust tests
Remove the date plugin deprecation from the global ignore list.

User interface changes

None

API changes

MigrateField plugins now have a weight field in their annotation that determines which one is used for a given field and Drupal core version.

Data model changes

None.

CommentFileSizeAuthor
#44 3004456-44.drupal.Add-a-weighting-option-to-MigrateField-plugins-definition-and-lower-weight-of-deprecated-date-plugin-so-it-isnt-used.patch23.47 KBmikelutz
#40 interdiff.3004456.36-40.txt696 bytesmikelutz
#40 3004456-40.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch23.45 KBmikelutz
#36 interdiff.3004456.35-36.txt1.12 KBmikelutz
#36 3004456-36.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch23.45 KBmikelutz
#35 3004456-35.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch23.46 KBmikelutz
#35 interdiff.3004456.33-35.txt1.95 KBmikelutz
#33 interdiff.3004456.28-33.txt15.11 KBmikelutz
#33 3004456-33.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch23.46 KBmikelutz
#29 interdiff.3004456.27-28.txt697 bytesmikelutz
#28 interdiff.3004456.27-28.txt0 bytesmikelutz
#28 3004456-28.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch24.39 KBmikelutz
#27 interdiff.3004456.24-27.txt1.95 KBmikelutz
#27 3004456-27.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch24.34 KBmikelutz
#24 interdiff.3004456.20-24.txt10.6 KBmikelutz
#24 3004456-24.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch22.85 KBmikelutz
#20 interdiff.3004456.19-20.txt16 KBmikelutz
#20 3004456-20.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch19.27 KBmikelutz
#19 interdiff.3004456.17-19.txt1.3 KBmikelutz
#19 3004456-19.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch6.64 KBmikelutz
#17 interdiff.3004456.13-17.txt2.93 KBmikelutz
#17 3004456-17.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch6.48 KBmikelutz
#13 interdiff.3004456.9-13.txt1.6 KBmikelutz
#13 3004456-13.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch4.8 KBmikelutz
#9 interdiff.3004456.3-9.txt5.35 KBmikelutz
#9 3004456-9.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch3.94 KBmikelutz
#8 3004456-7.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch5 KBmikelutz
#6 interdiff.3004456-3-6.txt6.04 KBmikelutz
#6 3004456-6.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch5.51 KBmikelutz
#3 3004456-3.drupal.Fix-DateField-is-deprecated-in-Drupal-84x-and-will-be-removed-before-Drupal-90x-Use-DrupaldatetimePluginmigratefieldDateField-instead.patch6.29 KBmikelutz
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mikelutz created an issue. See original summary.

mikelutz’s picture

mikelutz’s picture

mikelutz’s picture

Status: Active » Needs work
mikelutz’s picture

Status: Needs work » Needs review

Well, the patch itself needs a little polish, but I guess I need some feedback on the approach. It passes tests with a small patch, and I don't think it actually breaks anything.

mikelutz’s picture

mikelutz’s picture

Issue summary: View changes
Status: Needs work » Needs review

From discussion with @phenaproxima, I guess we don't actually have to change the annotation class to add a flag. I don't love undefined/undocumented annotations as signalling flags, so I'm open to other ideas, but we need to somehow exclude that plugin from being called.

mikelutz’s picture

Assigned: mikelutz » Unassigned
maxocub’s picture

Status: Needs review » Needs work

I like this. I think we should also open a follow-up to add the deprecated flag to other deprecated filed plugins so they are not use by accident.

  1. +++ b/core/modules/comment/src/Plugin/migrate/D7Comment.php
    @@ -32,7 +32,8 @@ public function getProcess() {
    -          $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($field_type, [], $this);
    +          $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this);
    +          $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, [], $this);
    

    After a quick grep, I found that this should also be done in the Drupal\user\Plugin\migrate\User class.

  2. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -44,8 +44,9 @@ public function getPluginIdFromFieldType($field_type, array $configuration = [],
         $definitions = $this->getDefinitions();
    +
         foreach ($definitions as $plugin_id => $definition) {
    

    Super-nit: this extra line is not useful and only add noise to the patch.

mikelutz’s picture

So I did add the line to User, but here's the deal..

Both User and D7 comment wrap that plugin creation in a ->hasDefinition() check. So even if a plugin declares itself eligible to process a field in the type_map, it's still not getting used in either case unless it's plugin_id matches the field name. All changing it from createInstance to getPluginIdFromFieldType does is eliminates that deprecated plugin now. I did it on D7Comment because I had to to pass tests, but we have no date field on User in the fixture, so that one didn't trip. Both will still fail to find a field plugin if the plugin Id and field name don't match.

Both of these really need to use the node/taxonomy deriver pattern where the getPluginIdFromFieldType() is wrapped in a try/catch(PluginNotFoundException), or better yet have a pluginExistsForFieldType() method in MigrateFieldPluginManagerInterface so we don't use exceptions as a signal.

The rabbit hole of bugginess quickly took trying to fix anything in those two out of scope for this issue. User is being refactored in #2951550: Make service for field discovery for use in migrate entity derivers and D7Comment has an issue at #3005718: D7 comment migration does not properly migrate fields by comment bundle., so the initial patch was trying to make the minimum fixes I needed to do to solve this issue.

I removed the unneeded extra line.

maxocub’s picture

Status: Needs review » Reviewed & tested by the community

@mikelutz: Thanks for the explanation. I agree D7Comment and User should be refactored to be more like the node and taxonomy term derivers.
RTBC provided the tests are green.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

This is not how we deprecate plugins. We've learnt the hard way that plugins should be deprecated via the constructor and not in the main part of the class. See https://www.drupal.org/core/deprecation#how-plugin

Then there'll be no random keys in the annotation and no unintended API breaks such as:

+++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
@@ -45,7 +45,7 @@ public function getPluginIdFromFieldType($field_type, array $configuration = [],
     foreach ($definitions as $plugin_id => $definition) {
-      if (in_array($core, $definition['core'])) {
+      if (in_array($core, $definition['core']) && empty($definition['deprecated'])) {
         if (array_key_exists($field_type, $definition['type_map']) || $field_type === $plugin_id) {
           return $plugin_id;
         }
mikelutz’s picture

I'm happy to move the @trigger_error into the constructor, but we still need a way to make sure it isn't returned from getPluginIdFromFieldType(). I'm open to suggestions.

mikelutz’s picture

alexpott’s picture

  1. +++ b/core/modules/datetime/src/Plugin/migrate/field/d6/DateField.php
    @@ -18,7 +16,8 @@
    + *   weight = 9999999
    

    This looks like a good flexible solution. +1 - this is why skipping deprecations is a bad idea means we don't solve these things at the right time.

  2. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -44,8 +44,12 @@ public function getPluginIdFromFieldType($field_type, array $configuration = [],
    +    uasort($definitions, function ($a, $b) {
    +      return $a['weight'] - $b['weight'];
    +    });
    

    Let's do uasort(definitions, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);

    But I also wonder if we should do a stable sort here - ie. sort by weight and plugin_id.

  3. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -44,8 +44,12 @@ public function getPluginIdFromFieldType($field_type, array $configuration = [],
    +      if (in_array($core, $definition['core']) && empty($definition['deprecated'])) {
    

    Can remove this change

mikelutz’s picture

mikelutz’s picture

Okay, here's a fleshed out version. I used a stable sort and moved it to an overridden getDefinitions method so we can cache the sort. I completely reworked the tests around MigrateFieldPluginManager. The updated tests caught a typo in the d6 link plugin definition (it's type_map referenced the d7 'link_field' field type instead of the d6 'link' field_type) so I fixed that here as well.

mikelutz’s picture

Title: Fix "DateField is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.x. Use \Drupal\datetime\Plugin\migrate\field\DateField instead." » Add a weighting option to MigrateField plugin's definition and lower weight of deprecated 'date' plugin so it isn't used
Issue summary: View changes
Issue tags: -Needs change record

Add CR, change IS and title to reflect what we are doing.

mikelutz’s picture

Issue summary: View changes
heddn’s picture

Status: Needs review » Needs work
+++ b/core/modules/migrate_drupal/tests/src/Unit/MigrateFieldPluginManagerTest.php
@@ -0,0 +1,182 @@
+    /* @var CacheBackendInterface $cache */
...
+    /* @var ModuleHandlerInterface $module_handler */

Nit: need full path to class.


+++ b/core/modules/migrate_drupal/tests/src/Unit/MigrateFieldPluginManagerTest.php
@@ -0,0 +1,182 @@
+        'weight' => 99999999,
...
+        'weight' => 0,
...
+        'weight' => 0,
...
+        'weight' => 0,
...
+        'weight' => 0,
...
+        'weight' => 0,

Except for the 99999 deprecated, can we remove the rest of these or at least some of these to test what happens when we don't explicitly define the weight?

mikelutz’s picture

After a discussion with @phenaproxima, I moved the sort into findDefinitions, which lets me inject the sort before the cache while still keeping more of the default discovery code path.

I added the namespaces to the test docs.

I can't remove the weight on that unit test, as it is simulating the result of the plugin discovery which already has the default value set in the annotation class applied. I did add a kernel test to check that the weight is set, and set to zero for all non-deprecated core plugins.

heddn’s picture

Valid thoughts. Here's a few more to consider.

  1. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -28,7 +28,25 @@ class MigrateFieldPluginManager extends MigratePluginManager implements MigrateF
    -   * {@inheritdoc}
    +   * Get the plugin ID from the field type.
    ...
       public function getPluginIdFromFieldType($field_type, array $configuration = [], MigrationInterface $migration = NULL) {
    

    Why did this inheritdoc go away?

  2. +++ b/core/modules/migrate_drupal/tests/src/Unit/MigrateFieldPluginManagerTest.php
    @@ -0,0 +1,227 @@
    +class MigrateFieldPluginManagerTestClass extends MigrateFieldPluginManager {
    

    Is this needed any more?

mikelutz’s picture

1 - I added documentation to the method to indicate how it was selecting which plugin to return.

2 - no, I'm still overriding the constructor to insert a mock discovery object.

mikelutz’s picture

FileSize
697 bytes

And the right diff...

heddn’s picture

So, is there any way to test that the weight annotation wasn't there before the cache clear? It would seem the answer is no.

mikelutz’s picture

No, the initial state of the cache would have to be part of the test configuration and set up by definition. For the purposes of that test though, I don't care about the previous state of the cache, all I care is that after the update hook runs, whatever the previous cache was, I end up with a useable plugin list. Which is why I didn't worry about populating it with anything other than an empty array.

phenaproxima’s picture

Status: Needs review » Needs work

Lookin' really good. I think this is very logical, and it's nice to see the deprecation moved into the constructor and out of the "global" deprecations. My feedback is mostly minor.

  1. +++ b/core/modules/datetime/src/Plugin/migrate/field/d6/DateField.php
    @@ -18,7 +16,8 @@
    + *   weight = 9999999
    

    Nit: This should have a trailing comma.

  2. +++ b/core/modules/link/src/Plugin/migrate/field/d6/LinkField.php
    @@ -10,7 +10,7 @@
    + *     "link" = "link"
    

    Same here.

  3. +++ b/core/modules/migrate_drupal/migrate_drupal.install
    @@ -31,3 +31,10 @@ function migrate_drupal_update_8502() {
    +/**
    + * Clear the Field Plugin Cache after adding weight annotation.
    + */
    +function migrate_drupal_update_8701() {
    +  \Drupal::service('plugin.manager.migrate.field')->clearCachedDefinitions();
    +}
    

    Let's replace this with an empty post-update hook, which will force a general cache clear and does not need a test.

  4. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -28,7 +28,25 @@ class MigrateFieldPluginManager extends MigratePluginManager implements MigrateF
    +   * type and core Drupal version, returning the lowest weighted plugin
    

    Can we say "Drupal core" instead of "core Drupal"?

  5. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -28,7 +28,25 @@ class MigrateFieldPluginManager extends MigratePluginManager implements MigrateF
    +   * supporting the provided core version, and who matches the field type either
    

    s/who/which

  6. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -28,7 +28,25 @@ class MigrateFieldPluginManager extends MigratePluginManager implements MigrateF
    +   * by plugin id, or in the type_map annotation keys.
    

    'id' should be ID. And can we add a @see annotation to this method, referring to the annotation class?

  7. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -28,7 +28,25 @@ class MigrateFieldPluginManager extends MigratePluginManager implements MigrateF
    +   * @param \Drupal\migrate\Plugin\MigrationInterface|null $migration
    

    We can remove the |null from here. "(optional)" covers it.

  8. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -28,7 +28,25 @@ class MigrateFieldPluginManager extends MigratePluginManager implements MigrateF
    +   *   The ID of the plugin for the field_type if available.
    

    field_type should be "field type".

  9. +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
    @@ -67,4 +85,27 @@ public function processDefinition(&$definition, $plugin_id) {
    +   * the plugin id, ensuring a stable, deterministic, and testable ordering of
    

    'id' --> ID

  10. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -3,54 +3,144 @@
    +    $this->assertEquals('link', $this->pluginManager->getPluginIdFromFieldType('link', ['core' => 6]));
    +    $this->assertEquals('link_field', $this->pluginManager->getPluginIdFromFieldType('link_field', ['core' => 7]));
    +    $this->assertEquals('image', $this->pluginManager->getPluginIdFromFieldType('image', ['core' => 7]));
    +    $this->assertEquals('file', $this->pluginManager->getPluginIdFromFieldType('file', ['core' => 7]));
    +    $this->assertEquals('d6_file', $this->pluginManager->getPluginIdFromFieldType('file', ['core' => 6]));
    +    $this->assertEquals('d6_text', $this->pluginManager->getPluginIdFromFieldType('text', ['core' => 6]));
    +    $this->assertEquals('d7_text', $this->pluginManager->getPluginIdFromFieldType('text', ['core' => 7]));
    

    Can we use assertSame() when comparing strings?

  11. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -3,54 +3,144 @@
    +    $nonexistent_plugins = [
    +      ['core' => 7, 'field_type' => 'filefield'],
    +      ['core' => 6, 'field_type' => 'link_field'],
    +      ['core' => 7, 'field_type' => 'link'],
    +      ['core' => 7, 'field_type' => 'd6_no_core_version_specified'],
    +    ];
    +
    +    foreach ($nonexistent_plugins as $plugin_info) {
    +      try {
    +        $this->pluginManager->getPluginIdFromFieldType($plugin_info['field_type'], ['core' => $plugin_info['core']]);
    +        $this->fail(sprintf("Looking up non-existent field plugin for field type '%s' in Drupal %d failed to throw expected '%s' exception", $plugin_info['field_type'], $plugin_info['core'], PluginNotFoundException::class));
    +      }
    +      catch (PluginNotFoundException $e) {
    +        $this->assertEquals($e->getMessage(), sprintf("Plugin ID '%s' was not found.", $plugin_info['field_type']));
    +      }
    

    We should probably replace this with a dataProvider pattern and $this->setExpectedException(), since it's more explicit and clear than $this->fail() in a try-catch.

  12. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -3,54 +3,144 @@
    +    $this->assertNotNull($plugin);
    

    This assertion is not needed (and therefore, neither is the $plugin variable).

  13. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -3,54 +3,144 @@
    +      if (in_array($id, $deprecated_plugins)) {
    

    in_array() should be called with TRUE as a third argument.

  14. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -3,54 +3,144 @@
    +        $this->assertEquals(9999999, $definition['weight']);
    +      }
    +      else {
    +        $this->assertEquals(0, $definition['weight']);
    

    Should be assertSame().

  15. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -3,54 +3,144 @@
    +  /**
    +   * Tests that HOOK_update_8701 clears the field plugin cache.
    +   */
    +  public function testUpdate8701() {
    +    /** @var \Drupal\Core\Cache\CacheBackendInterface $cache */
    +    $cache = $this->container->get('cache.discovery');
    +    $cache->set('migrate_plugins_field', [], Cache::PERMANENT);
    +    $definitions = $this->pluginManager->getDefinitions();
    +    $this->assertEquals([], $definitions);
    +
    +    module_load_include('install', 'migrate_drupal');
    +    migrate_drupal_update_8701();
    +
    +    $definitions = $this->pluginManager->getDefinitions();
    +    $this->assertEquals(20, count($definitions));
    +    foreach ($definitions as $id => $definition) {
    +      $this->assertArrayHasKey('weight', $definition);
    

    We can remove this once we replace the update function with an empty post-update.

  16. +++ b/core/modules/migrate_drupal/tests/src/Unit/MigrateFieldPluginManagerTest.php
    @@ -0,0 +1,227 @@
    +    $discovery = $this->prophesize(AnnotatedClassDiscovery::class);
    +    $discovery->getDefinitions()->willReturn($this->pluginFixtureData());
    +    $manager = new MigrateFieldPluginManagerTestClass('field', new \ArrayObject(), $cache, $module_handler, MigrateField::class, $discovery->reveal());
    

    Nice :)

  17. +++ b/core/modules/migrate_drupal/tests/src/Unit/MigrateFieldPluginManagerTest.php
    @@ -0,0 +1,227 @@
    +    try {
    +      $actual_plugin_id = $manager->getPluginIdFromFieldType($field_type, ['core' => $core]);
    +      $this->assertEquals($expected_plugin_id, $actual_plugin_id);
    +    }
    +    catch (PluginNotFoundException $e) {
    +      // We did not find a plugin, so assert that we didn't expect to.
    +      $this->assertFalse($expected_plugin_id, sprintf('Expected field plugin %s was not found by the field plugin manager', $expected_plugin_id));
    +    }
    

    This should use $this->setExpectedException() (the data provider can pass the expected exception class and message, if an exception is expected).

phenaproxima’s picture

Looks great. Two tiny nits:

  1. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -51,58 +50,72 @@ public function setUp() {
    +  public function nonExistantPluginExceptionsData() {
    

    Minor spelling error: this should be nonExistent.

  2. +++ b/core/modules/migrate_drupal/tests/src/Unit/MigrateFieldPluginManagerTest.php
    @@ -34,15 +34,11 @@ public function testWeights($field_type, $core, $expected_plugin_id) {
    +    $this->assertEquals($expected_plugin_id, $actual_plugin_id);
    

    This should be assertSame().

mikelutz’s picture

Issue summary: View changes

IS formatting fixes.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

RTBC on green for all backends. Thanks!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/link/src/Plugin/migrate/field/d6/LinkField.php
    @@ -10,7 +10,7 @@
    - *     "link_field" = "link"
    + *     "link" = "link",
    

    How come this change is necessary? And what is the impact on existing migrations due to this?

  2. +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
    @@ -8,49 +8,132 @@
    +        'core' => 7
    +        , 'field_type' => 'link',
    

    code style...

mikelutz’s picture

39.1 - I expanded the tests around field plugin discovery in this issue, and one of the tests I added checked that drupal 6 plugins wouldn't be created for drupal 7 only field names and vice versa. In Drupal 6 the CCK link field was called 'link', and in Drupal 7 it was called 'link_field'. The expanded test checks that there is no 'link_field' plugin for D6 nor a 'link' plugin for D7, among others. When I ran it, it failed by creating a D6 plugin for 'link_field', which it shouldn't. I didn't want to reduce the test coverage just to avoid fixing the typo. The plugin worked for link fields anyway because of the plugin id. There is no impact on existing migrations since there was no such thing as 'link_field' in Drupal 6, and the plugin is already used for D6 'link' fields.

.2 Fixed.

mikelutz’s picture

Status: Needs work » Needs review
phenaproxima’s picture

Issue tags: +Needs reroll

Looks like it needs a reroll...

mikelutz’s picture

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

All feedback seems to be addressed.

quietone’s picture

A question,

+++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManager.php
@@ -67,4 +87,27 @@ public function processDefinition(&$definition, $plugin_id) {
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php

+++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php
@@ -8,49 +8,132 @@
+    $this->assertSame('link', $this->pluginManager->getPluginIdFromFieldType('link', ['core' => 6]));
+    $this->assertSame('link_field', $this->pluginManager->getPluginIdFromFieldType('link_field', ['core' => 7]));
+    $this->assertSame('image', $this->pluginManager->getPluginIdFromFieldType('image', ['core' => 7]));
+    $this->assertSame('file', $this->pluginManager->getPluginIdFromFieldType('file', ['core' => 7]));
+    $this->assertSame('d6_file', $this->pluginManager->getPluginIdFromFieldType('file', ['core' => 6]));
+    $this->assertSame('d6_text', $this->pluginManager->getPluginIdFromFieldType('text', ['core' => 6]));
+    $this->assertSame('d7_text', $this->pluginManager->getPluginIdFromFieldType('text', ['core' => 7]));
...
+    $this->assertSame('datetime', $this->pluginManager->getPluginIdFromFieldType('date', ['core' => 6]));

Why is a subset of the field plugins tested? Why these particular ones and not others? Notably all the reference fields are absent. Should all of them be tested? If this warrants a comment in code please, please sort the $modules list in the test. Otherwise, no worries

mikelutz’s picture

We could test more, but we aren't really testing the plugins here, we are testing the logic of the plugin manager. I only added to what was there and changed the asserts to not use the deprecated assertIdentical. The ones tested are a mix across drupal versions, ones found by typemap, and ones found by plugin Id. I added ones around the new deprecation weights. To me it seems enough to prove the logic of the manager, and I assume the individual plugins are themselves tested elsewhere.

quietone’s picture

Thanks, just wanted to be sure I wasn't missing something. I spotted that the reference ones weren't they and wondered, so I asked without giving it much thought. So, no change needed. 'Tis great as it is.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Nice approach. I don't think we can backport this to 8.6.x, but if you strongly disagree please re-open.

Committed 6b14845 and pushed to 8.7.x. Thanks!

  • catch committed 6b14845 on 8.7.x
    Issue #3004456 by mikelutz, phenaproxima, alexpott, heddn, maxocub,...
mikelutz’s picture

I published the associated change record. I never expected this to be portable to 8.6. It does technically contain a bug fix in that it prevents the deprecated plugin from being called, however because of the BC shim left in place, this 'bug' has no negative side effects. The patch contains new functionality and should just be included in 8.7 Thanks!

Status: Fixed » Closed (fixed)

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