summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2016-06-27 14:32:56 (GMT)
committerNathaniel Catchpole2016-06-27 14:32:56 (GMT)
commitd8d92b591798a1e126d317e23a1d641a6b5389c0 (patch)
tree786d00fee46baf7ed26975713f6833be1f8b6c99
parenta64ea9d39b1d263a14a4093ca1e35092c7d1384f (diff)
Issue #2698083 by quietone, Sam152, Mac_Weber, vasi: D6->D8: Migrating links without leading slash leads to fatal error
-rw-r--r--core/modules/link/src/Plugin/migrate/process/d6/CckLink.php28
-rw-r--r--core/modules/link/tests/src/Unit/Plugin/migrate/process/d6/CckLinkTest.php56
-rw-r--r--core/modules/migrate_drupal/tests/fixtures/drupal6.php4
-rw-r--r--core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php26
4 files changed, 109 insertions, 5 deletions
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..2c03412 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 @@ class CckLink extends ProcessPluginBase implements ContainerFactoryPluginInterfa
}
/**
+ * Turn a Drupal 6 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 <front> component of the URL.
+ if (strpos($uri, '<front>') === 0) {
+ $uri = substr($uri, strlen('<front>'));
+ }
+
+ // 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 @@ class CckLink extends ProcessPluginBase implements ContainerFactoryPluginInterfa
}
// 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 @@
+<?php
+
+namespace Drupal\Tests\link\Unit\Plugin\migrate\process\d6;
+
+use Drupal\link\Plugin\migrate\process\d6\CckLink;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @group Link
+ */
+class CckLinkTest extends UnitTestCase {
+
+ /**
+ * Test the url transformations in the CckLink process plugin.
+ *
+ * @dataProvider canonicalizeUriDataProvider
+ */
+ public function testCanonicalizeUri($url, $expected) {
+ $link_plugin = new CckLink([], '', [], $this->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' => [
+ '<front>',
+ 'internal:/',
+ ],
+ 'Front page with query' => [
+ '<front>?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 7d1c020..97ed43e 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
@@ -3402,9 +3402,9 @@ $connection->insert('content_type_story')
'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 7f07d11..5f48683 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 @@ class MigrateNodeTest extends MigrateNodeTestBase {
$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 @@ class MigrateNodeTest extends MigrateNodeTestBase {
->condition('vid', '3')
->execute();
+ // 2. Add a 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);