Problem/Motivation

We are still migrating a Website from Drupal 6 to Drupal 8. After migrating a content-type with a link field I encountered this error when viewing the migrated node:

Error: Unsupported operand types in Drupal\Core\Utility\LinkGenerator->generate() (line 153 of core/lib/Drupal/Core/Utility/LinkGenerator.php).

After setting a breakpoint in transform() in Drupal\link\Plugin\migrate\process\FieldLink I noticed, that the link attributes got triple-serialized in our D6 page:
$value['attributes'] = 's:13:"s:6:"a:0:{}";";'

This seems to have happened to others too, but the other issue fixes the symptoms: https://www.drupal.org/project/drupal/issues/2596937

Proposed resolution

As I don’t think a triple-serialized value ever worked, my suggestion is to reset the attributes to an empty array in case it is not working after the first two unserialize-attempts.

Remaining tasks

None

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

Prevent link field migration from creating invalid link attributes.

Comments

Nebel54 created an issue. See original summary.

nebel54’s picture

StatusFileSize
new724 bytes

Here is a patch

nebel54’s picture

Status: Active » Needs review
heddn’s picture

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

NW because needs tests.

nlisgo’s picture

Status: Needs work » Needs review
StatusFileSize
new1.39 KB
new1.39 KB
new2.1 KB

The last submitted patch, 5: 3045211-5-testonly.patch, failed testing. View results

heddn’s picture

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

Small nit only.

+++ b/core/modules/link/tests/src/Unit/Plugin/migrate/process/FieldLinkTest.php
@@ -89,4 +89,26 @@ public function canonicalizeUriDataProvider() {
+    ], $this->getMock(MigrateExecutableInterface::class), $this->getMockBuilder(Row::class)->disableOriginalConstructor()->getMock(), NULL);
...
+    ], $this->getMock(MigrateExecutableInterface::class), $this->getMockBuilder(Row::class)->disableOriginalConstructor()->getMock(), NULL);

Row is a simple value object, no need to disable the constructor on it.

nlisgo’s picture

Status: Needs work » Needs review
StatusFileSize
new1.5 KB
new2.02 KB

Addressing feedback in #7. Also, we can reuse the MigrateExecutableInterface and Row mocks.

heddn’s picture

Status: Needs review » Needs work
+++ b/core/modules/link/tests/src/Unit/Plugin/migrate/process/FieldLinkTest.php
@@ -89,4 +89,27 @@ public function canonicalizeUriDataProvider() {
+    $row = $this->getMock(Row::class);

Super nit: no need for a mock, just use the row object class directly. new Row()

nlisgo’s picture

Assigned: Unassigned » nlisgo
Issue tags: +Seattle2019
nlisgo’s picture

Status: Needs work » Needs review
StatusFileSize
new777 bytes
new140.4 KB
heddn’s picture

Status: Needs review » Reviewed & tested by the community

All feedback addressed

quietone’s picture

Status: Reviewed & tested by the community » Needs work

Sorry, something is amiss. The patch in #8 is 2K and the next one in #11 is 140K. Thats is a big difference with no explanation. Maybe the wrong patch? Not working from HEAD?

yogeshmpawar’s picture

Assigned: nlisgo » yogeshmpawar
yogeshmpawar’s picture

Assigned: yogeshmpawar » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2 KB
new777 bytes

Added Updated patch with an interdiff.

heddn’s picture

Status: Needs review » Reviewed & tested by the community

Thanks Vicki, I only looked at the interdiff. Didn't notice the size of the patch. This looks more sane now.

nlisgo’s picture

Apologies. I was juggling issues. Thanks @yogeshmpawar.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 15: 3045211-15.patch, failed testing. View results

heddn’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed a71337b86f to 8.8.x and 7530980cf9 to 8.7.x. Thanks!

+++ b/core/modules/link/src/Plugin/migrate/process/FieldLink.php
@@ -119,7 +119,9 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
+    if (!$attributes || !is_array($attributes)) {

This can be made less complex.
if (!is_array($attributes)) {

Made this change on commit because it is very minor.

  • alexpott committed a71337b on 8.8.x
    Issue #3045211 by nlisgo, yogeshmpawar, Nebel54, heddn, quietone:...

  • alexpott committed 7530980 on 8.7.x
    Issue #3045211 by nlisgo, yogeshmpawar, Nebel54, heddn, quietone:...

Status: Fixed » Closed (fixed)

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