Issue #2233883 by benjy, hussainweb, ultimike: Link migration needs to convert source url into the appropriate route format for storage
parent
145b53cef3
commit
a5f0e6afb2
|
@ -60,3 +60,26 @@ field.value.link:
|
||||||
url:
|
url:
|
||||||
type: string
|
type: string
|
||||||
label: 'URL'
|
label: 'URL'
|
||||||
|
options:
|
||||||
|
type: mapping
|
||||||
|
label: 'Link options'
|
||||||
|
mapping:
|
||||||
|
query:
|
||||||
|
type: sequence
|
||||||
|
label: 'Url query key value pairs'
|
||||||
|
sequence:
|
||||||
|
- type: string
|
||||||
|
fragment:
|
||||||
|
type: string
|
||||||
|
label: 'Url fragment'
|
||||||
|
absolute:
|
||||||
|
type: boolean
|
||||||
|
label: 'Is this Url absolute'
|
||||||
|
https:
|
||||||
|
type: boolean
|
||||||
|
label: 'If the Url should use a secure protocol'
|
||||||
|
attributes:
|
||||||
|
type: sequence
|
||||||
|
label: 'Link attributes'
|
||||||
|
sequence:
|
||||||
|
- type: string
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\migrate_drupal\Plugin\CckFieldMigrateSourceInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\migrate_drupal\Plugin;
|
||||||
|
|
||||||
|
use Drupal\migrate\Plugin\MigrateSourceInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an interface for cck field sources that need per type processing.
|
||||||
|
*/
|
||||||
|
interface CckFieldMigrateSourceInterface extends MigrateSourceInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field data used for determining the field type in the LoadEntity
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* An array of cck field data.
|
||||||
|
*/
|
||||||
|
public function fieldData();
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ use Drupal\migrate\Exception\RequirementsException;
|
||||||
use Drupal\migrate\MigrateException;
|
use Drupal\migrate\MigrateException;
|
||||||
use Drupal\migrate\Plugin\SourceEntityInterface;
|
use Drupal\migrate\Plugin\SourceEntityInterface;
|
||||||
use Drupal\migrate_drupal\Plugin\MigrateLoadInterface;
|
use Drupal\migrate_drupal\Plugin\MigrateLoadInterface;
|
||||||
|
use Drupal\migrate_drupal\Plugin\CckFieldMigrateSourceInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for entity load plugins.
|
* Base class for entity load plugins.
|
||||||
|
@ -82,8 +83,33 @@ class LoadEntity extends PluginBase implements MigrateLoadInterface {
|
||||||
$migration = $storage->create($values);
|
$migration = $storage->create($values);
|
||||||
try {
|
try {
|
||||||
$migration->getSourcePlugin()->checkRequirements();
|
$migration->getSourcePlugin()->checkRequirements();
|
||||||
$fields = array_keys($migration->getSourcePlugin()->fields());
|
|
||||||
$migration->process += array_combine($fields, $fields);
|
$source_plugin = $migration->getSourcePlugin();
|
||||||
|
// Discuss simplifying per field type processing.
|
||||||
|
// @see https://www.drupal.org/node/2395993
|
||||||
|
if ($source_plugin instanceof CckFieldMigrateSourceInterface) {
|
||||||
|
foreach ($source_plugin->fieldData() as $field_name => $data) {
|
||||||
|
// Specifically process the link field until core is fixed.
|
||||||
|
// @see https://www.drupal.org/node/2235457
|
||||||
|
if ($data['type'] == 'link') {
|
||||||
|
$migration->process[$field_name] = [
|
||||||
|
'plugin' => 'd6_cck_link',
|
||||||
|
'source' => [
|
||||||
|
$field_name,
|
||||||
|
$field_name . '_title',
|
||||||
|
$field_name . '_attributes',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$migration->process[$field_name] = $field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$fields = array_keys($migration->getSourcePlugin()->fields());
|
||||||
|
$migration->process += array_combine($fields, $fields);
|
||||||
|
}
|
||||||
$migrations[$migration->id()] = $migration;
|
$migrations[$migration->id()] = $migration;
|
||||||
}
|
}
|
||||||
catch (RequirementsException $e) {
|
catch (RequirementsException $e) {
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\migrate_drupal\Plugin\migrate\process\d6\CckLink.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\migrate_drupal\Plugin\migrate\process\d6;
|
||||||
|
|
||||||
|
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||||
|
use Drupal\migrate\MigrateExecutable;
|
||||||
|
use Drupal\migrate\Row;
|
||||||
|
use Drupal\migrate\Plugin\migrate\process\Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @MigrateProcessPlugin(
|
||||||
|
* id = "d6_cck_link"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
class CckLink extends Route implements ContainerFactoryPluginInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) {
|
||||||
|
list($url, $title, $attributes) = $value;
|
||||||
|
|
||||||
|
// Drupal 6 link attributes are double serialized.
|
||||||
|
$attributes = unserialize(unserialize($attributes));
|
||||||
|
$route_plugin_value = [$url, []];
|
||||||
|
$route = parent::transform($route_plugin_value, $migrate_executable, $row, $destination_property);
|
||||||
|
|
||||||
|
// Massage the values into the correct form for the link.
|
||||||
|
$route['options']['attributes'] = $attributes;
|
||||||
|
$route['title'] = $title;
|
||||||
|
return $route;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -57,6 +57,7 @@ class FieldInstanceDefaults extends ProcessPluginBase {
|
||||||
if (!empty($widget_settings['default_value'][0]['url'])) {
|
if (!empty($widget_settings['default_value'][0]['url'])) {
|
||||||
$default['title'] = $widget_settings['default_value'][0]['title'];
|
$default['title'] = $widget_settings['default_value'][0]['title'];
|
||||||
$default['url'] = $widget_settings['default_value'][0]['url'];
|
$default['url'] = $widget_settings['default_value'][0]['url'];
|
||||||
|
$default['options'] = ['attributes' => []];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
|
||||||
use Drupal\migrate\Plugin\SourceEntityInterface;
|
use Drupal\migrate\Plugin\SourceEntityInterface;
|
||||||
use Drupal\migrate\Row;
|
use Drupal\migrate\Row;
|
||||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||||
|
use Drupal\migrate_drupal\Plugin\CckFieldMigrateSourceInterface;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +20,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||||
* id = "d6_cck_field_values"
|
* id = "d6_cck_field_values"
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
class CckFieldValues extends DrupalSqlBase implements SourceEntityInterface {
|
class CckFieldValues extends DrupalSqlBase implements SourceEntityInterface, CckFieldMigrateSourceInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The join options between the node and the node_revisions table.
|
* The join options between the node and the node_revisions table.
|
||||||
|
@ -261,6 +262,16 @@ class CckFieldValues extends DrupalSqlBase implements SourceEntityInterface {
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function fieldData() {
|
||||||
|
$field_info = $this->getSourceFieldInfo($this->configuration['bundle']);
|
||||||
|
$field_info['nid'] = ['type' => 'number'];
|
||||||
|
$field_info['type'] = ['type' => 'text'];
|
||||||
|
return $field_info;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1021,7 +1021,7 @@ class Drupal6FieldInstance extends Drupal6DumpBase {
|
||||||
'global_settings' => 'a:7:{s:10:"attributes";a:4:{s:6:"target";s:7:"default";s:3:"rel";s:8:"nofollow";s:5:"class";s:0:"";s:5:"title";s:10:"Link Title";}s:7:"display";a:1:{s:10:"url_cutoff";s:2:"80";}s:3:"url";i:0;s:5:"title";s:8:"required";s:11:"title_value";s:0:"";s:13:"enable_tokens";s:0:"";s:12:"validate_url";i:1;}',
|
'global_settings' => 'a:7:{s:10:"attributes";a:4:{s:6:"target";s:7:"default";s:3:"rel";s:8:"nofollow";s:5:"class";s:0:"";s:5:"title";s:10:"Link Title";}s:7:"display";a:1:{s:10:"url_cutoff";s:2:"80";}s:3:"url";i:0;s:5:"title";s:8:"required";s:11:"title_value";s:0:"";s:13:"enable_tokens";s:0:"";s:12:"validate_url";i:1;}',
|
||||||
'multiple' => 0,
|
'multiple' => 0,
|
||||||
'db_storage' => 1,
|
'db_storage' => 1,
|
||||||
'db_columns' => 'a:0:{}',
|
'db_columns' => 'a:3:{s:3:"url";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:2048;s:8:"not null";b:0;s:8:"sortable";b:1;}s:5:"title";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:255;s:8:"not null";b:0;s:8:"sortable";b:1;}s:10:"attributes";a:3:{s:4:"type";s:4:"text";s:4:"size";s:6:"medium";s:8:"not null";b:0;}}',
|
||||||
'active' => 1,
|
'active' => 1,
|
||||||
))
|
))
|
||||||
->values(array(
|
->values(array(
|
||||||
|
|
|
@ -513,6 +513,23 @@ class Drupal6Node extends Drupal6DumpBase {
|
||||||
'unsigned' => TRUE,
|
'unsigned' => TRUE,
|
||||||
'not null' => FALSE
|
'not null' => FALSE
|
||||||
),
|
),
|
||||||
|
'field_test_link_url' => array(
|
||||||
|
'description' => 'The link field',
|
||||||
|
'type' => 'varchar',
|
||||||
|
'length' => 2048,
|
||||||
|
'not null' => FALSE,
|
||||||
|
),
|
||||||
|
'field_test_link_title' => array(
|
||||||
|
'description' => 'The link field',
|
||||||
|
'type' => 'varchar',
|
||||||
|
'length' => 255,
|
||||||
|
'not null' => FALSE,
|
||||||
|
),
|
||||||
|
'field_test_link_attributes' => array(
|
||||||
|
'description' => 'The link attributes',
|
||||||
|
'type' => 'text',
|
||||||
|
'not null' => FALSE,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'primary key' => array('vid'),
|
'primary key' => array('vid'),
|
||||||
));
|
));
|
||||||
|
@ -525,7 +542,10 @@ class Drupal6Node extends Drupal6DumpBase {
|
||||||
'field_test_three_value',
|
'field_test_three_value',
|
||||||
'field_test_integer_selectlist_value',
|
'field_test_integer_selectlist_value',
|
||||||
'field_test_identical1_value',
|
'field_test_identical1_value',
|
||||||
'field_test_identical2_value'
|
'field_test_identical2_value',
|
||||||
|
'field_test_link_url',
|
||||||
|
'field_test_link_title',
|
||||||
|
'field_test_link_attributes',
|
||||||
))
|
))
|
||||||
->values(array(
|
->values(array(
|
||||||
'nid' => 1,
|
'nid' => 1,
|
||||||
|
@ -535,6 +555,45 @@ class Drupal6Node extends Drupal6DumpBase {
|
||||||
'field_test_integer_selectlist_value' => '3412',
|
'field_test_integer_selectlist_value' => '3412',
|
||||||
'field_test_identical1_value' => 1,
|
'field_test_identical1_value' => 1,
|
||||||
'field_test_identical2_value' => 1,
|
'field_test_identical2_value' => 1,
|
||||||
|
'field_test_link_url' => 'http://drupal.org/project/drupal',
|
||||||
|
'field_test_link_title' => 'Drupal project page',
|
||||||
|
'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";";',
|
||||||
|
))
|
||||||
|
->values(array(
|
||||||
|
'nid' => 1,
|
||||||
|
'vid' => 2,
|
||||||
|
'uid' => 1,
|
||||||
|
'field_test_three_value' => '42.42',
|
||||||
|
'field_test_integer_selectlist_value' => '3412',
|
||||||
|
'field_test_identical1_value' => 1,
|
||||||
|
'field_test_identical2_value' => 1,
|
||||||
|
'field_test_link_url' => 'http://drupal.org/project/drupal',
|
||||||
|
'field_test_link_title' => 'Drupal project page',
|
||||||
|
'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";',
|
||||||
|
))
|
||||||
|
->values(array(
|
||||||
|
'nid' => 2,
|
||||||
|
'vid' => 3,
|
||||||
|
'uid' => 1,
|
||||||
|
'field_test_three_value' => '23.2',
|
||||||
|
'field_test_integer_selectlist_value' => '1244',
|
||||||
|
'field_test_identical1_value' => 1,
|
||||||
|
'field_test_identical2_value' => 1,
|
||||||
|
'field_test_link_url' => 'http://groups.drupal.org/',
|
||||||
|
'field_test_link_title' => 'Drupal Groups',
|
||||||
|
'field_test_link_attributes' => 's:6:"a:0:{}";',
|
||||||
|
))
|
||||||
|
->values(array(
|
||||||
|
'nid' => 2,
|
||||||
|
'vid' => 5,
|
||||||
|
'uid' => 1,
|
||||||
|
'field_test_three_value' => '23.2',
|
||||||
|
'field_test_integer_selectlist_value' => '1244',
|
||||||
|
'field_test_identical1_value' => 1,
|
||||||
|
'field_test_identical2_value' => 1,
|
||||||
|
'field_test_link_url' => 'http://groups.drupal.org/',
|
||||||
|
'field_test_link_title' => 'Drupal Groups',
|
||||||
|
'field_test_link_attributes' => 's:6:"a:0:{}";',
|
||||||
))
|
))
|
||||||
->execute();
|
->execute();
|
||||||
$this->setModuleVersion('content', 6001);
|
$this->setModuleVersion('content', 6001);
|
||||||
|
|
|
@ -22,7 +22,7 @@ class MigrateCckFieldValuesTest extends MigrateNodeTestBase {
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $modules = array('node', 'text');
|
public static $modules = array('node', 'text', 'link');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
@ -105,6 +105,17 @@ class MigrateCckFieldValuesTest extends MigrateNodeTestBase {
|
||||||
'bundle' => 'story',
|
'bundle' => 'story',
|
||||||
))->save();
|
))->save();
|
||||||
|
|
||||||
|
entity_create('field_storage_config', array(
|
||||||
|
'entity_type' => 'node',
|
||||||
|
'field_name' => 'field_test_link',
|
||||||
|
'type' => 'link',
|
||||||
|
))->save();
|
||||||
|
entity_create('field_config', array(
|
||||||
|
'entity_type' => 'node',
|
||||||
|
'field_name' => 'field_test_link',
|
||||||
|
'bundle' => 'story',
|
||||||
|
))->save();
|
||||||
|
|
||||||
// Add some id mappings for the dependant migrations.
|
// Add some id mappings for the dependant migrations.
|
||||||
$id_mappings = array(
|
$id_mappings = array(
|
||||||
'd6_field_formatter_settings' => array(
|
'd6_field_formatter_settings' => array(
|
||||||
|
@ -143,10 +154,15 @@ class MigrateCckFieldValuesTest extends MigrateNodeTestBase {
|
||||||
$this->assertEqual($node->field_test_identical1->value, '1', 'Integer value is correct');
|
$this->assertEqual($node->field_test_identical1->value, '1', 'Integer value is correct');
|
||||||
$this->assertEqual($node->field_test_identical2->value, '1', 'Integer value is correct');
|
$this->assertEqual($node->field_test_identical2->value, '1', 'Integer value is correct');
|
||||||
|
|
||||||
|
// Test that link fields are migrated.
|
||||||
|
$this->assertIdentical($node->field_test_link->url, 'http://drupal.org/project/drupal');
|
||||||
|
$this->assertIdentical($node->field_test_link->title, 'Drupal project page');
|
||||||
|
$this->assertIdentical($node->field_test_link->route_parameters, []);
|
||||||
|
$this->assertIdentical($node->field_test_link->options['attributes'], ['target' => '_blank']);
|
||||||
|
|
||||||
$planet_node = Node::load(3);
|
$planet_node = Node::load(3);
|
||||||
$this->assertEqual($planet_node->field_multivalue->value, 33);
|
$this->assertEqual($planet_node->field_multivalue->value, 33);
|
||||||
$this->assertEqual($planet_node->field_multivalue[1]->value, 44);
|
$this->assertEqual($planet_node->field_multivalue[1]->value, 44);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,7 @@ class MigrateFieldInstanceTest extends MigrateDrupalTestBase {
|
||||||
$this->assertEqual($field->getSettings(), $expected);
|
$this->assertEqual($field->getSettings(), $expected);
|
||||||
$this->assertEqual('default link title', $entity->field_test_link->title, 'Field field_test_link default title is correct.');
|
$this->assertEqual('default link title', $entity->field_test_link->title, 'Field field_test_link default title is correct.');
|
||||||
$this->assertEqual('http://drupal.org', $entity->field_test_link->url, 'Field field_test_link default title is correct.');
|
$this->assertEqual('http://drupal.org', $entity->field_test_link->url, 'Field field_test_link default title is correct.');
|
||||||
|
$this->assertIdentical($entity->field_test_link->options['attributes'], []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue