diff --git a/core/modules/field/migration_templates/d7_field_instance.yml b/core/modules/field/migration_templates/d7_field_instance.yml index f3518c9..4261946 100644 --- a/core/modules/field/migration_templates/d7_field_instance.yml +++ b/core/modules/field/migration_templates/d7_field_instance.yml @@ -19,15 +19,15 @@ process: settings: plugin: d7_field_instance_settings source: - - instance_settings - - widget_settings + - settings + - widget - field_settings default_value_function: '' default_value: plugin: d7_field_instance_defaults source: - default_value - - widget_settings + - widget translatable: translatable destination: plugin: entity:field_config diff --git a/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml b/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml index e2bbcf4..85a67cb 100644 --- a/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml +++ b/core/modules/field/migration_templates/d7_field_instance_widget_settings.yml @@ -52,7 +52,7 @@ process: plugin: field_instance_widget_settings source: - 'widget/type' - - widget_settings + - 'widget/settings' 'options/third_party_settings': 'constants/third_party_settings' destination: plugin: component_entity_form_display diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceDefaults.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceDefaults.php index 2a46381..a6707bd 100644 --- a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceDefaults.php +++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceDefaults.php @@ -19,6 +19,11 @@ class FieldInstanceDefaults extends ProcessPluginBase { public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { list($default_value, $widget_settings) = $value; $widget_type = $widget_settings['type']; + $default_value = $default_value ?: []; + if ($widget_type == 'email_textfield' && $default_value) { + $default_value[0]['value'] = $default_value[0]['email']; + unset($default_value[0]['email']); + } $default = []; diff --git a/core/modules/field/src/Plugin/migrate/source/d7/Field.php b/core/modules/field/src/Plugin/migrate/source/d7/Field.php index d9aef91..348c28c 100644 --- a/core/modules/field/src/Plugin/migrate/source/d7/Field.php +++ b/core/modules/field/src/Plugin/migrate/source/d7/Field.php @@ -19,36 +19,46 @@ class Field extends DrupalSqlBase { */ public function query() { $query = $this->select('field_config', 'fc') - ->distinct() - ->fields('fc') + ->fields('fc', ['field_name', 'type', 'module', 'storage_type', 'storage_module', 'locked', 'data', 'cardinality', 'translatable']) ->fields('fci', ['entity_type']) ->condition('fc.active', 1) + ->condition('fc.storage_active', 1) ->condition('fc.deleted', 0) - ->condition('fc.storage_active', 1); + ->condition('fci.deleted', 0); + $query->addField('fci', 'field_name', 'instance_field_name'); + $query->addField('fci', 'entity_type', 'instance_entity_type'); + $query->addField('fci', 'bundle', 'instance_bundle'); + $query->addField('fci', 'data', 'instance_data'); $query->join('field_config_instance', 'fci', 'fc.id = fci.field_id'); - return $query; } /** * {@inheritdoc} */ - public function fields() { - return [ - 'field_name' => $this->t('The name of this field.'), - 'type' => $this->t('The type of this field.'), - 'module' => $this->t('The module that implements the field type.'), - 'storage' => $this->t('The field storage.'), - 'locked' => $this->t('Locked'), - 'cardinality' => $this->t('Cardinality'), - 'translatable' => $this->t('Translatable'), - ]; + protected function initializeIterator() { + $rows = []; + + foreach ($this->prepareQuery()->execute() as $result) { + $field_id = $result['entity_type'] . ':' . $result['field_name']; + $bundle = $result['instance_bundle']; + + foreach (array_keys($this->getFieldFields()) as $property) { + $rows[$field_id][$property] = $result[$property]; + } + + foreach (array_keys($this->getFieldInstanceFields()) as $property) { + $rows[$field_id]['instances'][$bundle][$property] = $result['instance_' . $property]; + } + } + + return new \ArrayIterator($rows); } /** * {@inheritdoc} */ - public function prepareRow(Row $row, $keep = TRUE) { + public function prepareRow(Row $row) { foreach (unserialize($row->getSourceProperty('data')) as $key => $value) { $row->setSourceProperty($key, $value); } @@ -58,6 +68,56 @@ public function prepareRow(Row $row, $keep = TRUE) { /** * {@inheritdoc} */ + public function count() { + return $this->initializeIterator()->count(); + } + + /** + * {@inheritdoc} + */ + public function fields() { + $fields = $this->getFieldFields(); + $fields['instances'] = $this->t('The field instances.'); + return $fields; + } + + /** + * Returns available fields for the Field source plugin. + * + * @return array + * Available fields in the source. + */ + public function getFieldFields() { + return [ + 'field_name' => $this->t('The field name.'), + 'type' => $this->t('The field type.'), + 'module' => $this->t('The module that implements the field type.'), + 'locked' => $this->t('Whether the field is locked.'), + 'data' => $this->t('The field data.'), + 'cardinality' => $this->t('The field cardinality.'), + 'translatable' => $this->t('The field translatability.'), + 'entity_type' => $this->t('The field entity type.'), + ]; + } + + /** + * Returns available fields for the FieldInstance source plugin. + * + * @return array + * Available fields in the source. + */ + public function getFieldInstanceFields() { + return [ + 'field_name' => $this->t('The field name.'), + 'entity_type' => $this->t('The field entity type.'), + 'bundle' => $this->t('The field instance bundle.'), + 'data' => $this->t('The field instance data.'), + ]; + } + + /** + * {@inheritdoc} + */ public function getIds() { return [ 'field_name' => [ diff --git a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php index d06336e..61f19b3 100644 --- a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php +++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php @@ -2,8 +2,8 @@ namespace Drupal\field\Plugin\migrate\source\d7; +use Drupal\field\Plugin\migrate\source\d7\Field; use Drupal\migrate\Row; -use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; /** * Drupal 7 field instances source from database. @@ -13,77 +13,37 @@ * source_provider = "field" * ) */ -class FieldInstance extends DrupalSqlBase { +class FieldInstance extends Field { /** * {@inheritdoc} */ - public function query() { - $query = $this->select('field_config_instance', 'fci') - ->fields('fci') - ->condition('fci.deleted', 0) - ->condition('fc.active', 1) - ->condition('fc.deleted', 0) - ->condition('fc.storage_active', 1) - ->fields('fc', ['type']); - - $query->innerJoin('field_config', 'fc', 'fci.field_id = fc.id'); - $query->addField('fc', 'data', 'field_data'); - - // Optionally filter by entity type and bundle. - if (isset($this->configuration['entity_type'])) { - $query->condition('fci.entity_type', $this->configuration['entity_type']); - - if (isset($this->configuration['bundle'])) { - $query->condition('fci.bundle', $this->configuration['bundle']); + protected function initializeIterator() { + $rows = []; + + foreach ($this->prepareQuery()->execute() as $result) { + $instance_key = $result['instance_entity_type'] . ':' . $result['instance_bundle'] . ':' . $result['instance_field_name']; + + foreach (array_keys($this->getFieldInstanceFields()) as $instance_property) { + $rows[$instance_key][$instance_property] = $result['instance_' . $instance_property]; + } + + foreach (array_keys($this->getFieldFields()) as $field_property) { + $rows[$instance_key]['field_definition'][$field_property] = $result[$field_property]; } } - return $query; - } - - /** - * {@inheritdoc} - */ - public function fields() { - return [ - 'field_name' => $this->t('The machine name of field.'), - 'entity_type' => $this->t('The entity type.'), - 'bundle' => $this->t('The entity bundle.'), - 'default_value' => $this->t('Default value'), - 'instance_settings' => $this->t('Field instance settings.'), - 'widget_settings' => $this->t('Widget settings.'), - 'display_settings' => $this->t('Display settings.'), - 'field_settings' => $this->t('Field settings.'), - ]; + return new \ArrayIterator($rows); } /** * {@inheritdoc} */ public function prepareRow(Row $row) { - $data = unserialize($row->getSourceProperty('data')); - - $row->setSourceProperty('label', $data['label']); - $row->setSourceProperty('description', $data['description']); - $row->setSourceProperty('required', $data['required']); - - $default_value = !empty($data['default_value']) ? $data['default_value'] : []; - if ($data['widget']['type'] == 'email_textfield' && $default_value) { - $default_value[0]['value'] = $default_value[0]['email']; - unset($default_value[0]['email']); - } - $row->setSourceProperty('default_value', $default_value); - - // Settings. - $row->setSourceProperty('instance_settings', $data['settings']); - $row->setSourceProperty('widget_settings', $data['widget']); - $row->setSourceProperty('display_settings', $data['display']); - - // This is for parity with the d6_field_instance plugin. - $row->setSourceProperty('widget_type', $data['widget']['type']); + $field_definition = $row->getSourceProperty('field_definition'); + $row->setSourceProperty('type', $field_definition['type']); - $field_data = unserialize($row->getSourceProperty('field_data')); + $field_data = unserialize($field_definition['data']); $row->setSourceProperty('field_settings', $field_data['settings']); $translatable = FALSE; @@ -98,19 +58,33 @@ public function prepareRow(Row $row) { } } else { - // This is not a node entity. Get the translatable value from the source - // field_config table. - $data = unserialize($row->getSourceProperty('field_data')); - $translatable = $data['translatable']; + $translatable = $field_data['translatable']; } $row->setSourceProperty('translatable', $translatable); + // This is for backward compatibility and parity with the d6_field_instance + // plugin. + $data = unserialize($row->getSourceProperty('data')); + $row->setSourceProperty('instance_settings', $data['settings']); + $row->setSourceProperty('widget_settings', $data['widget']); + $row->setSourceProperty('display_settings', $data['display']); + $row->setSourceProperty('widget_type', $data['widget']['type']); + return parent::prepareRow($row); } /** * {@inheritdoc} */ + public function fields() { + $fields = $this->getFieldInstanceFields(); + $fields['field_definition'] = $this->t('Field definition'); + return $fields; + } + + /** + * {@inheritdoc} + */ public function getIds() { return [ 'entity_type' => [ diff --git a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php index ab2fe8e..d23fbe2 100644 --- a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php +++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldTest.php @@ -122,7 +122,7 @@ public function testFields() { /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ $migration = $this->getMigration('d7_field'); $this->assertSame($migration->getSourcePlugin() - ->count(), $migration->getIdMap()->processedCount()); + ->count(), (int) $migration->getIdMap()->processedCount()); } } diff --git a/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php b/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php index 4e78ee5..bb71418 100644 --- a/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php +++ b/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php @@ -34,7 +34,7 @@ public function getFieldWidgetMap() { public function processFieldInstance(MigrationInterface $migration) { $process = [ 'plugin' => 'static_map', - 'source' => 'instance_settings/title', + 'source' => 'settings/title', 'bypass' => TRUE, 'map' => [ 'disabled' => DRUPAL_DISABLED,