Problem/Motivation

When migrating Drupal 6/7 comments the hostname value is not migrated correctly to Drupal 8. IP-addresses in the D6 comments.hostname column should go to comment_field_data.hostname in D8. But the destination values are all set to the IP of the localhost (127.0.0.1). Other values, such as creation timestamp and mail are migrated in good order.

Proposed resolution

Only assign current request client IP when no hostname has been previously set.

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Sutharsan created an issue. See original summary.

mikeryan’s picture

Title: Wrong hostname (IP) when D6 migrating comments » Comment::preSave() unconditionally sets hostname to client host
Component: migration system » comment.module

The problem here is that the comment entity preSave() unconditionally sets the hostname to \Drupal::request()->getClientIP() - anything passed in by migration (or anything else creating comments programmatically) for hostname is simply ignored. I think preSave() should respect an explicit hostname, and default to getClientIP() when it's absent

rosinegrean’s picture

Assigned: Unassigned » rosinegrean
Status: Active » Needs review
FileSize
757 bytes

Hey,

Something like this ?

mikeryan’s picture

Issue tags: +Needs tests

Yep, just what I had in mind...

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

edemus’s picture

Tested patch against drupal 8.2.3 and works perfectly, thanks.

dawehner’s picture

Status: Needs review » Needs work

Given we need tests

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

claudiu.cristea’s picture

Assigned: rosinegrean » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
4.33 KB
3.57 KB

Added tests and also a test-only patch.

I used for tests, documentation reserved IPs. See https://en.wikipedia.org/wiki/Reserved_IP_addresses

This part:

if (!$this->getHostname()) {
  // Ensure a client host from the current request.
  $this->setHostname(\Drupal::request()->getClientIP());
}

should be moved outside if ($this->isNew()) {...} to act also on updates. Otherwise parent comments, that are stubs during migration, will get an empty host and will never update.

claudiu.cristea’s picture

Issue summary: View changes

IS update.

Status: Needs review » Needs work

The last submitted patch, 10: 2687977-10-test-only.patch, failed testing.

claudiu.cristea’s picture

Status: Needs work » Needs review

Only the "test only" failed, the main patch is green.

jofitz’s picture

Status: Needs review » Reviewed & tested by the community

Nice, short fix. Good test coverage.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -151,8 +151,10 @@ public function preSave(EntityStorageInterface $storage) {
       }
-      // Add the values which aren't passed into the function.
       $this->setThread($thread);
+    }
+    if (!$this->getHostname()) {
+      // Ensure a client host from the current request.
...
     }
   }

Why are we moving this outside the if ...->isNew()? According to #10 it is because

Otherwise parent comments, that are stubs during migration, will get an empty host and will never update.

Is this tested?

claudiu.cristea’s picture

Status: Needs review » Reviewed & tested by the community

@alexpott, yes is tested in the D6 test where we have a parent comment. The test revealed me this problem. Without the fix, comment with cid 3 will return an empty hostname. This is because, that one being parent, is created first as stub, so the hostname is initially set to NULL. Then, when the stub is updating and is receiving a valid hostname, that part is not triggered because, this time, $this->isNew() === FALSE.

alexpott’s picture

Priority: Normal » Major
Status: Reviewed & tested by the community » Needs review
FileSize
769 bytes
4.37 KB

Given this is data loss during migration it is at least a major. I'm not sure this is critical data though.

+++ b/core/modules/comment/src/Entity/Comment.php
@@ -151,8 +151,10 @@ public function preSave(EntityStorageInterface $storage) {
-      // Add the values which aren't passed into the function.
       $this->setThread($thread);
+    }
+    if (!$this->getHostname()) {
+      // Ensure a client host from the current request.
       $this->setHostname(\Drupal::request()->getClientIP());
     }

But if I move this the kernel test doesn't fail :(

Also it doesn't make sense because if a stub is created then it'll have the host set to \Drupal::request()->getClientIP().

claudiu.cristea’s picture

Issue summary: View changes

@alexpott, well, yes. I cannot reproduce anymore the situation where I got an empty IP for cid 3. I'm fixing the IS.

@Jo Fitzgerald, are you so kind to re-review if turns green?

Berdir’s picture

Wondering if a better fix would actually be to make this a default value callback instead of setting it on preSave(). But that's a bigger change.

alexpott’s picture

Issue tags: +Needs followup

@Berdir yeah - maybe a follow-up. Do the simple fix for the data integrity issue here and do it right in an 8.4.x followup.

claudiu.cristea’s picture

claudiu.cristea’s picture

claudiu.cristea’s picture

Issue tags: -Needs followup
jofitz’s picture

Status: Needs review » Reviewed & tested by the community

Bearing in mind the follow-up, I think this simple fix can now be set as RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 012bca1 to 8.4.x and b1642ec to 8.3.x. Thanks!

  • alexpott committed 012bca1 on 8.4.x
    Issue #2687977 by claudiu.cristea, alexpott, prics: Comment::preSave()...

  • alexpott committed b1642ec on 8.3.x
    Issue #2687977 by claudiu.cristea, alexpott, prics: Comment::preSave()...

Status: Fixed » Closed (fixed)

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