Issue #2538000 by phenaproxima, quietone, benjy, mikeryan: The d6_node plugin should fetch CCK field values
parent
d6d3f6a6ca
commit
6ad0357621
|
@ -1,17 +0,0 @@
|
|||
id: d6_cck_field_revision
|
||||
label: Drupal 6 field revisions
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
load:
|
||||
plugin: drupal_entity
|
||||
bundle_migration: d6_node_type
|
||||
source:
|
||||
plugin: d6_cck_field_revision
|
||||
process:
|
||||
vid: vid
|
||||
destination:
|
||||
plugin: entity_revision:node
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_cck_field_values
|
||||
- d6_node_revision:*
|
|
@ -1,21 +0,0 @@
|
|||
id: d6_cck_field_values
|
||||
label: Drupal 6 field values
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
load:
|
||||
plugin: drupal_entity
|
||||
bundle_migration: d6_node_type
|
||||
source:
|
||||
plugin: d6_cck_field_values
|
||||
process:
|
||||
nid:
|
||||
plugin: migration
|
||||
migration: d6_node
|
||||
source: nid
|
||||
destination:
|
||||
plugin: entity:node
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_node:*
|
||||
- d6_field_formatter_settings
|
||||
- d6_field_instance_widget_settings
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\migrate_drupal\Plugin\migrate\source\d6\CckFieldRevision.
|
||||
*/
|
||||
|
||||
namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
|
||||
|
||||
/**
|
||||
* Drupal 6 cck field revision source.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_cck_field_revision"
|
||||
* )
|
||||
*/
|
||||
class CckFieldRevision extends CckFieldValues {
|
||||
|
||||
/**
|
||||
* The join options between the node and the node_revisions_table.
|
||||
*/
|
||||
const JOIN = 'n.nid = nr.nid AND n.vid <> nr.vid';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
// Use all the node fields plus the vid that identifies the version.
|
||||
return parent::fields() + array('vid' => t('The primary identifier for this version.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['vid']['type'] = 'integer';
|
||||
$ids['vid']['alias'] = 'nr';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,318 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\migrate_drupal\Plugin\migrate\source\d6\CckFieldValues.
|
||||
*/
|
||||
|
||||
namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Plugin\SourceEntityInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
use Drupal\migrate_drupal\Plugin\CckFieldMigrateSourceInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Drupal 6 cck field source.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_cck_field_values"
|
||||
* )
|
||||
*/
|
||||
class CckFieldValues extends DrupalSqlBase implements SourceEntityInterface, CckFieldMigrateSourceInterface {
|
||||
|
||||
/**
|
||||
* The join options between the node and the node_revisions table.
|
||||
*/
|
||||
const JOIN = 'n.vid = nr.vid';
|
||||
|
||||
/**
|
||||
* The source field information for complex node fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $sourceFieldInfo;
|
||||
|
||||
/**
|
||||
* Information on which tables exist.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tables;
|
||||
|
||||
/**
|
||||
* TRUE when CCK is enabled and the schema is correct.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $cckSchemaCorrect;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
// Select node in its last revision.
|
||||
$query = $this->select('node_revisions', 'nr')
|
||||
->fields('n', array(
|
||||
'nid',
|
||||
'type',
|
||||
))
|
||||
->fields('nr', array(
|
||||
'vid',
|
||||
))
|
||||
->condition('type', $this->configuration['bundle']);
|
||||
$query->innerJoin('node', 'n', static::JOIN);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$bundle = $row->getSourceProperty('type');
|
||||
// Pick up simple CCK fields.
|
||||
$cck_table = "content_type_$bundle";
|
||||
if ($this->tableExists($cck_table)) {
|
||||
$query = $this->select($cck_table, 'f')->condition('vid', $row->getSourceProperty('vid'));
|
||||
// The main column for the field should be rendered with the field name,
|
||||
// not the column name (e.g., field_foo rather than field_foo_value).
|
||||
$field_info = $this->getSourceFieldInfo($bundle);
|
||||
foreach ($field_info as $field_name => $info) {
|
||||
if (isset($info['columns']) && !$info['multiple'] && $info['db_storage']) {
|
||||
$i = 0;
|
||||
$data = FALSE;
|
||||
foreach ($info['columns'] as $display_name => $column_name) {
|
||||
if ($i++ == 0) {
|
||||
$query->addField('f', $column_name, $field_name);
|
||||
}
|
||||
else {
|
||||
// The database API won't allow colons in column aliases, so we
|
||||
// will accept the default alias, and fix up the field names later.
|
||||
// Remember how to translate the field names.
|
||||
if ($info['type'] == 'filefield' &&
|
||||
(strpos($display_name, ':list') || strpos($display_name, ':description'))) {
|
||||
if (!$data) {
|
||||
//$this->fileDataFields[] = $field_name . '_data';
|
||||
$query->addField('f', $field_name . '_data');
|
||||
$data = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$query->addField('f', $column_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The $query only contains single value CCK fields and so when the only
|
||||
// CCK field attached to a content type is a multi-valued CCK field then
|
||||
// this query would be invalid. Checking the count tells us if any single
|
||||
// fields have been added the query.
|
||||
if (count($query->getFields())) {
|
||||
if ($results = $query->execute()->fetchAssoc()) {
|
||||
$source = $row->getSource();
|
||||
// We diff the results with the source to find any field columns
|
||||
// in the content type's main table.
|
||||
$new_fields = array_diff_key($results, $source);
|
||||
foreach ($new_fields as $key => $value) {
|
||||
$row->setSourceProperty($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle fields that have their own table.
|
||||
foreach ($this->getSourceFieldInfo($bundle) as $field_name => $field_info) {
|
||||
if ($field_info['multiple'] || !$field_info['db_storage']) {
|
||||
// Select the data.
|
||||
$table = "content_$field_name";
|
||||
$field_query = $this
|
||||
->select($table, 't')
|
||||
->condition('vid', $row->getSourceProperty('vid'));
|
||||
if ($field_info['multiple']) {
|
||||
$field_query->addField('t', 'delta');
|
||||
}
|
||||
$data = FALSE;
|
||||
foreach ($field_info['columns'] as $display_name => $column_name) {
|
||||
// The database API won't allow colons in column aliases, so we
|
||||
// will accept the default alias, and fix up the field names later.
|
||||
// Remember how to translate the field names.
|
||||
if ($field_info['type'] == 'filefield' &&
|
||||
(strpos($display_name, ':list') || strpos($display_name, ':description'))) {
|
||||
if (!$data) {
|
||||
//$this->fileDataFields[] = $field_name . '_data';
|
||||
$field_query->addField('t', $field_name . '_data');
|
||||
$data = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$field_query->addField('t', $column_name);
|
||||
}
|
||||
}
|
||||
|
||||
if ($field_info['multiple']) {
|
||||
foreach ($field_query->execute() as $field_row) {
|
||||
foreach ($field_info['columns'] as $display_name => $column_name) {
|
||||
list ( , $column) = explode(':', $display_name);
|
||||
$property_path = $field_name . Row::PROPERTY_SEPARATOR . $field_row['delta'] . Row::PROPERTY_SEPARATOR . $column;
|
||||
$row->setSourceProperty($property_path, $field_row[$column_name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($field_row = $field_query->execute()->fetchAssoc()) {
|
||||
foreach ($field_info['columns'] as $display_name => $column_name) {
|
||||
$row->setSourceProperty(str_replace(':', Row::PROPERTY_SEPARATOR, $display_name), $field_row[$column_name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the complex field info.
|
||||
*
|
||||
* @param string $bundle
|
||||
* The bundle for which fields we want.
|
||||
*
|
||||
* @return array
|
||||
* An array of field info keyed by field name.
|
||||
*/
|
||||
protected function getSourceFieldInfo($bundle) {
|
||||
if (!isset($this->sourceFieldInfo)) {
|
||||
$this->sourceFieldInfo = array();
|
||||
if ($this->tableExists('content_node_field_instance')) {
|
||||
// Get each field attached to this type.
|
||||
$query = $this->select('content_node_field_instance', 'i')
|
||||
->fields('i', array(
|
||||
'label',
|
||||
'widget_settings',
|
||||
'field_name',
|
||||
))
|
||||
->condition('type_name', $bundle);
|
||||
|
||||
$query->innerJoin('content_node_field', 'f', 'i.field_name = f.field_name');
|
||||
$query->fields('f', array(
|
||||
'field_name',
|
||||
'type',
|
||||
'db_columns',
|
||||
'global_settings',
|
||||
'multiple',
|
||||
'db_storage')
|
||||
);
|
||||
|
||||
$results = $query->execute();
|
||||
foreach ($results as $row) {
|
||||
$field_name = trim($row['field_name']);
|
||||
$db_columns = $db_columns = !empty($row['db_columns']) ? unserialize($row['db_columns']) : array();
|
||||
$columns = array();
|
||||
foreach ($db_columns as $column_name => $column_info) {
|
||||
// Special handling for the stuff packed into filefield's "data"
|
||||
if ($row['type'] == 'filefield' && $column_name == 'data') {
|
||||
$widget_settings = unserialize($row['widget_settings']);
|
||||
$global_settings = unserialize($row['global_settings']);
|
||||
|
||||
if (!empty($widget_settings['custom_alt'])) {
|
||||
$columns[$field_name . ':alt'] = $field_name . '_alt';
|
||||
}
|
||||
if (!empty($widget_settings['custom_title'])) {
|
||||
$columns[$field_name . ':title'] = $field_name . '_title';
|
||||
}
|
||||
if (!empty($global_settings['description_field'])) {
|
||||
$columns[$field_name . ':description'] = $field_name . '_description';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$display_name = $field_name . ':' . $column_name;
|
||||
$column_name = $field_name . '_' . $column_name;
|
||||
$columns[$display_name] = $column_name;
|
||||
}
|
||||
}
|
||||
$this->sourceFieldInfo[$field_name] = array(
|
||||
'label' => $row['label'],
|
||||
'type' => $row['type'],
|
||||
'columns' => $columns,
|
||||
'multiple' => $row['multiple'],
|
||||
'db_storage' => $row['db_storage'],
|
||||
'bundle' => $bundle,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->sourceFieldInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = array(
|
||||
'nid' => $this->t('Node ID'),
|
||||
'type' => $this->t('Type'),
|
||||
);
|
||||
foreach ($this->getSourceFieldInfo($this->configuration['bundle']) as $field_name => $field_data) {
|
||||
$fields[$field_name] = $field_data['label'];
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fieldData() {
|
||||
$field_info = $this->getSourceFieldInfo($this->configuration['bundle']);
|
||||
$field_info['nid'] = ['type' => 'number'];
|
||||
$field_info['type'] = ['type' => 'varchar'];
|
||||
return $field_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['nid']['type'] = 'integer';
|
||||
$ids['nid']['alias'] = 'n';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bundleMigrationRequired() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityTypeId() {
|
||||
return 'node';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a specific CCK table exists.
|
||||
*/
|
||||
protected function tableExists($table) {
|
||||
if (!isset($this->tables[$table])) {
|
||||
$this->tables[$table] = $this->cckSchemaCorrect() && $this->getDatabase()->schema()->tableExists($table);
|
||||
}
|
||||
return $this->tables[$table];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether CCK is enabled and is using the right schema.
|
||||
*/
|
||||
protected function cckSchemaCorrect() {
|
||||
if (!isset($this->cckSchemaCorrect)) {
|
||||
$this->cckSchemaCorrect = $this->moduleExists('content') && $this->getModuleSchemaVersion('content') >= 6001;
|
||||
}
|
||||
return $this->cckSchemaCorrect;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\migrate_drupal\Tests\d6\MigrateCckFieldRevisionTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\migrate_drupal\Tests\d6;
|
||||
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\node\Tests\Migrate\d6\MigrateNodeTestBase;
|
||||
|
||||
/**
|
||||
* CCK field revision migration.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateCckFieldRevisionTest extends MigrateNodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('field', 'filter', 'node', 'text');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test',
|
||||
'type' => 'text',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_two',
|
||||
'type' => 'integer',
|
||||
'cardinality' => -1,
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_two',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
|
||||
// Add some id mappings for the dependant migrations.
|
||||
$id_mappings = array(
|
||||
'd6_cck_field_values' => array(
|
||||
array(array(1), array(1)),
|
||||
),
|
||||
'd6_node' => array(
|
||||
array(array(1), array(1)),
|
||||
array(array(2), array(2)),
|
||||
),
|
||||
'd6_node_revision' => array(
|
||||
array(array(1), array(1)),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
$migrations = entity_load_multiple('migration', array('d6_cck_field_revision:*'));
|
||||
foreach ($migrations as $migration) {
|
||||
$executable = new MigrateExecutable($migration, $this);
|
||||
$executable->import();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CCK revision migration from Drupal 6 to 8.
|
||||
*/
|
||||
public function testCckFieldRevision() {
|
||||
$node = \Drupal::entityManager()->getStorage('node')->loadRevision(2);
|
||||
$this->assertIdentical('1', $node->id(), 'Node 1 loaded.');
|
||||
$this->assertIdentical('2', $node->getRevisionId(), 'Node 1 revision 2loaded.');
|
||||
}
|
||||
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\migrate_drupal\Tests\d6\MigrateCckFieldValuesTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\migrate_drupal\Tests\d6;
|
||||
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Tests\Migrate\d6\MigrateNodeTestBase;
|
||||
|
||||
/**
|
||||
* CCK field content migration.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateCckFieldValuesTest extends MigrateNodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'text', 'filter', 'link', 'file');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('file');
|
||||
|
||||
$node = entity_create('node', array(
|
||||
'type' => 'story',
|
||||
'nid' => 2,
|
||||
'vid' => 12,
|
||||
'revision_log' => '',
|
||||
'title' => $this->randomString(),
|
||||
));
|
||||
$node->enforceIsNew();
|
||||
$node->save();
|
||||
|
||||
$planet_nodes = [
|
||||
4 => 6,
|
||||
5 => 8,
|
||||
6 => 9,
|
||||
7 => 10,
|
||||
8 => 11,
|
||||
];
|
||||
foreach ($planet_nodes as $nid => $vid) {
|
||||
$node = entity_create('node', array(
|
||||
'type' => 'test_planet',
|
||||
'nid' => $nid,
|
||||
'vid' => $vid,
|
||||
'revision_log' => '',
|
||||
'title' => $this->randomString(),
|
||||
));
|
||||
$node->enforceIsNew();
|
||||
$node->save();
|
||||
}
|
||||
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test',
|
||||
'type' => 'text',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_two',
|
||||
'type' => 'integer',
|
||||
'cardinality' => -1,
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_two',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_three',
|
||||
'type' => 'decimal',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_three',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_integer_selectlist',
|
||||
'type' => 'integer',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_integer_selectlist',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_exclude_unset',
|
||||
'type' => 'text',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_exclude_unset',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_multivalue',
|
||||
'type' => 'decimal',
|
||||
'precision' => '10',
|
||||
'scale' => '2',
|
||||
'cardinality' => -1,
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_multivalue',
|
||||
'bundle' => 'test_planet',
|
||||
))->save();
|
||||
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_identical1',
|
||||
'type' => 'integer',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_identical1',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_identical2',
|
||||
'type' => 'integer',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_identical2',
|
||||
'bundle' => 'story',
|
||||
))->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();
|
||||
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_filefield',
|
||||
'type' => 'file',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_test_filefield',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
|
||||
// Add some id mappings for the dependant migrations.
|
||||
$id_mappings = array(
|
||||
'd6_field_formatter_settings' => array(
|
||||
array(array('page', 'default', 'node', 'field_test'), array('node', 'page', 'default', 'field_test')),
|
||||
),
|
||||
'd6_field_instance_widget_settings' => array(
|
||||
array(array('page', 'field_test'), array('node', 'page', 'default', 'test')),
|
||||
),
|
||||
'd6_node' => array(
|
||||
array(array(1), array(1)),
|
||||
array(array(2), array(2)),
|
||||
array(array(3), array(3)),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
|
||||
$migrations = entity_load_multiple('migration', array('d6_cck_field_values:*'));
|
||||
foreach ($migrations as $migration) {
|
||||
$executable = new MigrateExecutable($migration, $this);
|
||||
$executable->import();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CCK migration from Drupal 6 to 8.
|
||||
*/
|
||||
public function testCckFields() {
|
||||
$node = Node::load(1);
|
||||
|
||||
$this->assertIdentical('This is a shared text field', $node->field_test->value);
|
||||
$this->assertIdentical('filtered_html', $node->field_test->format);
|
||||
$this->assertIdentical('10', $node->field_test_two->value);
|
||||
$this->assertIdentical('20', $node->field_test_two[1]->value);
|
||||
|
||||
$this->assertIdentical('42.42', $node->field_test_three->value, 'Single field second value is correct.');
|
||||
$this->assertIdentical('3412', $node->field_test_integer_selectlist[0]->value);
|
||||
$this->assertIdentical('1', $node->field_test_identical1->value, 'Integer value is correct');
|
||||
$this->assertIdentical('1', $node->field_test_identical2->value, 'Integer value is correct');
|
||||
$this->assertIdentical('This is a field with exclude unset.', $node->field_test_exclude_unset->value, 'Field with exclude unset is correct.');
|
||||
|
||||
// Test that link fields are migrated.
|
||||
$this->assertIdentical('https://www.drupal.org/project/drupal', $node->field_test_link->uri);
|
||||
$this->assertIdentical('Drupal project page', $node->field_test_link->title);
|
||||
$this->assertIdentical(['target' => '_blank'], $node->field_test_link->options['attributes']);
|
||||
|
||||
// Test the file field meta.
|
||||
$this->assertIdentical('desc', $node->field_test_filefield->description);
|
||||
$this->assertIdentical('5', $node->field_test_filefield->target_id);
|
||||
|
||||
$planet_node = Node::load(3);
|
||||
$value_1 = $planet_node->field_multivalue->value;
|
||||
$value_2 = $planet_node->field_multivalue[1]->value;
|
||||
|
||||
// SQLite does not support scales for float data types so we need to convert
|
||||
// the value manually.
|
||||
if ($this->container->get('database')->driver() == 'sqlite') {
|
||||
$value_1 = sprintf('%01.2f', $value_1);
|
||||
$value_2 = sprintf('%01.2f', $value_2);
|
||||
}
|
||||
$this->assertIdentical('33.00', $value_1);
|
||||
$this->assertIdentical('44.00', $value_2);
|
||||
}
|
||||
|
||||
}
|
|
@ -77,8 +77,6 @@ class MigrateDrupal6Test extends MigrateFullDrupalTestBase {
|
|||
'd6_block_content_type',
|
||||
'd6_book',
|
||||
'd6_book_settings',
|
||||
'd6_cck_field_values:*',
|
||||
'd6_cck_field_revision:*',
|
||||
'd6_comment_type',
|
||||
'd6_comment',
|
||||
'd6_comment_entity_display',
|
||||
|
|
|
@ -32,6 +32,13 @@ class Node extends DrupalSqlBase implements SourceEntityInterface {
|
|||
*/
|
||||
protected $filterDefaultFormat;
|
||||
|
||||
/**
|
||||
* Cached field and field instance definitions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldInfo;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -115,9 +122,130 @@ class Node extends DrupalSqlBase implements SourceEntityInterface {
|
|||
if ($row->getSourceProperty('format') === '0') {
|
||||
$row->setSourceProperty('format', $this->filterDefaultFormat);
|
||||
}
|
||||
|
||||
if ($this->moduleExists('content') && $this->getModuleSchemaVersion('content') >= 6001) {
|
||||
foreach ($this->getFieldValues($row) as $field => $values) {
|
||||
foreach ($values as $delta => $item) {
|
||||
foreach ($item as $column => $value) {
|
||||
if (strpos($column, $field) === 0) {
|
||||
$key = substr($column, strlen($field) + 1);
|
||||
$values[$delta][$key] = $value;
|
||||
unset($values[$delta][$column]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$row->setSourceProperty($field, $values);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets CCK field values for a node.
|
||||
*
|
||||
* @param \Drupal\migrate\Row $node
|
||||
* The node.
|
||||
*
|
||||
* @return array
|
||||
* CCK field values, keyed by field name.
|
||||
*/
|
||||
protected function getFieldValues(Row $node) {
|
||||
$values = [];
|
||||
foreach ($this->getFieldInfo($node->getSourceProperty('type')) as $field => $info) {
|
||||
$values[$field] = $this->getCckData($info, $node);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets CCK field and instance definitions from the database.
|
||||
*
|
||||
* @param string $node_type
|
||||
* The node type for which to get field info.
|
||||
*
|
||||
* @return array
|
||||
* Field and instance information for the node type, keyed by field name.
|
||||
*/
|
||||
protected function getFieldInfo($node_type) {
|
||||
if (!isset($this->fieldInfo)) {
|
||||
$this->fieldInfo = [];
|
||||
|
||||
// Query the database directly for all CCK field info.
|
||||
$query = $this->select('content_node_field_instance', 'cnfi');
|
||||
$query->join('content_node_field', 'cnf', 'cnf.field_name = cnfi.field_name');
|
||||
$query->fields('cnfi');
|
||||
$query->fields('cnf');
|
||||
|
||||
foreach ($query->execute() as $field) {
|
||||
$this->fieldInfo[ $field['type_name'] ][ $field['field_name'] ] = $field;
|
||||
}
|
||||
|
||||
foreach ($this->fieldInfo as $type => $fields) {
|
||||
foreach ($fields as $field => $info) {
|
||||
foreach ($info as $property => $value) {
|
||||
if ($property == 'db_columns' || preg_match('/_settings$/', $property)) {
|
||||
$this->fieldInfo[$type][$field][$property] = unserialize($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isset($this->fieldInfo[$node_type]) ? $this->fieldInfo[$node_type] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves raw CCK field data for a node.
|
||||
*
|
||||
* @param array $field
|
||||
* A field and instance definition from getFieldInfo().
|
||||
* @param \Drupal\migrate\Row $node
|
||||
* The node.
|
||||
*
|
||||
* @return array
|
||||
* The field values, keyed by delta.
|
||||
*/
|
||||
protected function getCckData(array $field, Row $node) {
|
||||
$field_table = 'content_' . $field['field_name'];
|
||||
$node_table = 'content_type_' . $node->getSourceProperty('type');
|
||||
|
||||
/** @var \Drupal\Core\Database\Schema $db */
|
||||
$db = $this->getDatabase()->schema();
|
||||
|
||||
if ($db->tableExists($field_table)) {
|
||||
$query = $this->select($field_table, 't')->fields('t');
|
||||
|
||||
// If the delta column does not exist, add it as an expression to
|
||||
// normalize the query results.
|
||||
if (!$db->fieldExists($field_table, 'delta')) {
|
||||
$query->addExpression(0, 'delta');
|
||||
}
|
||||
}
|
||||
elseif ($db->tableExists($node_table)) {
|
||||
$query = $this->select($node_table, 't');
|
||||
|
||||
// Add every DB column CCK knows about.
|
||||
foreach (array_keys($field['db_columns']) as $column) {
|
||||
$query->addField('t', $field['field_name'] . '_' . $column);
|
||||
}
|
||||
|
||||
// Every row should have a delta of 0.
|
||||
$query->addExpression(0, 'delta');
|
||||
}
|
||||
|
||||
if (isset($query)) {
|
||||
return $query
|
||||
->condition('nid', $node->getSourceProperty('nid'))
|
||||
->condition('vid', $node->getSourceProperty('vid'))
|
||||
->execute()
|
||||
->fetchAllAssoc('delta');
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -18,12 +18,8 @@ class NodeTest extends MigrateSqlSourceTestCase {
|
|||
|
||||
const PLUGIN_CLASS = 'Drupal\node\Plugin\migrate\source\d6\Node';
|
||||
|
||||
// The fake Migration configuration entity.
|
||||
protected $migrationConfiguration = array(
|
||||
'id' => 'test',
|
||||
// Leave it empty for now.
|
||||
'idlist' => array(),
|
||||
// The fake configuration for the source.
|
||||
'source' => array(
|
||||
'plugin' => 'd6_node',
|
||||
),
|
||||
|
@ -79,10 +75,9 @@ class NodeTest extends MigrateSqlSourceTestCase {
|
|||
'format' => 1,
|
||||
),
|
||||
array(
|
||||
// Node fields.
|
||||
'nid' => 5,
|
||||
'vid' => 5,
|
||||
'type' => 'article',
|
||||
'type' => 'story',
|
||||
'language' => 'en',
|
||||
'title' => 'node title 5',
|
||||
'uid' => 1,
|
||||
|
@ -101,6 +96,9 @@ class NodeTest extends MigrateSqlSourceTestCase {
|
|||
'log' => '',
|
||||
'timestamp' => 1279308993,
|
||||
'format' => 1,
|
||||
'field_test_four' => array(
|
||||
array('value' => '3.14159'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -108,6 +106,50 @@ class NodeTest extends MigrateSqlSourceTestCase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->databaseContents['content_node_field'] = array(
|
||||
array(
|
||||
'field_name' => 'field_test_four',
|
||||
'type' => 'number_float',
|
||||
'global_settings' => 'a:0:{}',
|
||||
'required' => '0',
|
||||
'multiple' => '0',
|
||||
'db_storage' => '1',
|
||||
'module' => 'number',
|
||||
'db_columns' => 'a:1:{s:5:"value";a:3:{s:4:"type";s:5:"float";s:8:"not null";b:0;s:8:"sortable";b:1;}}',
|
||||
'active' => '1',
|
||||
'locked' => '0',
|
||||
),
|
||||
);
|
||||
$this->databaseContents['content_node_field_instance'] = array(
|
||||
array(
|
||||
'field_name' => 'field_test_four',
|
||||
'type_name' => 'story',
|
||||
'weight' => '3',
|
||||
'label' => 'Float Field',
|
||||
'widget_type' => 'number',
|
||||
'widget_settings' => 'a:0:{}',
|
||||
'display_settings' => 'a:0:{}',
|
||||
'description' => 'An example float field.',
|
||||
'widget_module' => 'number',
|
||||
'widget_active' => '1',
|
||||
),
|
||||
);
|
||||
$this->databaseContents['content_type_story'] = array(
|
||||
array(
|
||||
'nid' => 5,
|
||||
'vid' => 5,
|
||||
'uid' => 5,
|
||||
'field_test_four_value' => '3.14159',
|
||||
),
|
||||
);
|
||||
$this->databaseContents['system'] = array(
|
||||
array(
|
||||
'type' => 'module',
|
||||
'name' => 'content',
|
||||
'schema_version' => 6001,
|
||||
'status' => TRUE,
|
||||
),
|
||||
);
|
||||
foreach ($this->expectedResults as $k => $row) {
|
||||
foreach (array('nid', 'vid', 'title', 'uid', 'body', 'teaser', 'format', 'timestamp', 'log') as $field) {
|
||||
$this->databaseContents['node_revisions'][$k][$field] = $row[$field];
|
||||
|
|
Loading…
Reference in New Issue