diff --git a/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php b/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php index 47c2f8b..663b9a3 100644 --- a/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php +++ b/core/modules/link/src/Plugin/migrate/process/d6/CckLink.php @@ -37,6 +37,32 @@ public static function create(ContainerInterface $container, array $configuratio } /** + * Turn a Drupal 6 or 7 URI into a Drupal 8-compatible format. + * + * @param string $uri + * The 'url' value from Drupal 6. + * + * @return string + * The Drupal 8-compatible URI. + * + * @see \Drupal\link\Plugin\Field\FieldWidget\LinkWidget::getUserEnteredStringAsUri() + */ + protected function canonicalizeUri($uri) { + // If we already have a scheme, we're fine. + if (empty($uri) || !is_null(parse_url($uri, PHP_URL_SCHEME))) { + return $uri; + } + + // Remove the component of the URL. + if (strpos($uri, '') === 0) { + $uri = substr($uri, strlen('')); + } + + // Add the internal: scheme and ensure a leading slash. + return 'internal:/' . ltrim($uri, '/'); + } + + /** * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { @@ -51,7 +77,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable } // Massage the values into the correct form for the link. - $route['uri'] = $value['url']; + $route['uri'] = $this->canonicalizeUri($value['url']); $route['options']['attributes'] = $attributes; $route['title'] = $value['title']; return $route; diff --git a/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/CckLinkTest.php b/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/CckLinkTest.php new file mode 100644 index 0000000..a96287a --- /dev/null +++ b/core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/CckLinkTest.php @@ -0,0 +1,56 @@ +getMock('\Drupal\migrate\Plugin\MigrationInterface')); + $transformed = $link_plugin->transform([ + 'url' => $url, + 'title' => '', + 'attributes' => serialize([]), + ], $this->getMock('\Drupal\migrate\MigrateExecutableInterface'), $this->getMockBuilder('\Drupal\migrate\Row')->disableOriginalConstructor()->getMock(), NULL); + $this->assertEquals($expected, $transformed['uri']); + } + + /** + * Data provider for testCanonicalizeUri. + */ + public function canonicalizeUriDataProvider() { + return [ + 'Simple front-page' => [ + '', + 'internal:/', + ], + 'Front page with query' => [ + '?query=1', + 'internal:/?query=1', + ], + 'No leading forward slash' => [ + 'node/10', + 'internal:/node/10', + ], + 'Leading forward slash' => [ + '/node/10', + 'internal:/node/10', + ], + 'Existing scheme' => [ + 'scheme:test', + 'scheme:test', + ], + ]; + } + +} diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/core/modules/migrate_drupal/tests/fixtures/drupal6.php index 4242cad..c123aeb 100644 --- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php +++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php @@ -3402,9 +3402,9 @@ 'field_test_three_value' => '101.00', 'field_test_identical1_value' => NULL, 'field_test_identical2_value' => NULL, - 'field_test_link_url' => 'http://www.example.com/buy-one-upon-a-time', + 'field_test_link_url' => 'node/10', 'field_test_link_title' => 'Buy it now', - 'field_test_link_attributes' => 'a:1:{s:6:"target";s:6:"_blank";}', + 'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";', 'field_test_date_value' => NULL, 'field_test_datestamp_value' => NULL, 'field_test_datetime_value' => NULL, diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php index 29bc9dc..76078dd 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php @@ -74,12 +74,19 @@ public function testNode() { $this->assertIdentical('test rev 3', $node->body->value); $this->assertIdentical('filtered_html', $node->body->format); - // Test that link fields are migrated. + // Test that a link field with an external link is migrated. $this->assertIdentical('http://groups.drupal.org/', $node->field_test_link->uri); $this->assertIdentical('Drupal Groups', $node->field_test_link->title); $this->assertIdentical([], $node->field_test_link->options['attributes']); - // Rerun migration with invalid link attributes and a different URL and + // Test that a link field with an internal link is migrated. + $node = Node::load(9); + $this->assertSame('internal:/node/10', $node->field_test_link->uri); + $this->assertSame('Buy it now', $node->field_test_link->title); + $this->assertSame(['attributes' => ['target' => '_blank']], $node->field_test_link->options); + + // Rerun migration with two source database changes. + // 1. Add an invalid link attributes and a different URL and // title. If only the attributes are changed the error does not occur. Database::getConnection('default', 'migrate') ->update('content_type_story') @@ -92,12 +99,27 @@ public function testNode() { ->condition('vid', '3') ->execute(); + // 2. Add an leading slash to an internal link. + Database::getConnection('default', 'migrate') + ->update('content_type_story') + ->fields([ + 'field_test_link_url' => '/node/10', + ]) + ->condition('nid', '9') + ->condition('vid', '12') + ->execute(); + $this->rerunMigration(); $node = Node::load(2); $this->assertIdentical('https://www.drupal.org/node/2127611', $node->field_test_link->uri); $this->assertIdentical('Migrate API in Drupal 8', $node->field_test_link->title); $this->assertIdentical([], $node->field_test_link->options['attributes']); + $node = Node::load(9); + $this->assertSame('internal:/node/10', $node->field_test_link->uri); + $this->assertSame('Buy it now', $node->field_test_link->title); + $this->assertSame(['attributes' => ['target' => '_blank']], $node->field_test_link->options); + // Test that we can re-import using the EntityContentBase destination. $title = $this->rerunMigration(); $node = Node::load(2);