From 3da4bc3b9dd32f9fe8fa840303888b6674bf506c Mon Sep 17 00:00:00 2001 From: Harings Rob Date: Fri, 27 Jan 2017 14:20:31 +0100 Subject: [PATCH] #29 Taxonomy support and improved tests --- .../src/Plugin/migrate/process/TagToId.php | 32 ++++ .../migrate/source/IntegrationDocuments.php | 67 ++++--- .../data/10931.json | 31 ++++ .../src/Kernel/MigrateDocumentEntityTest.php | 170 +++++++++++++++--- 4 files changed, 256 insertions(+), 44 deletions(-) create mode 100644 modules/integration_migrate/src/Plugin/migrate/process/TagToId.php create mode 100644 modules/integration_migrate/tests/modules/integration_migrate_entity/data/10931.json diff --git a/modules/integration_migrate/src/Plugin/migrate/process/TagToId.php b/modules/integration_migrate/src/Plugin/migrate/process/TagToId.php new file mode 100644 index 0000000..7e0628e --- /dev/null +++ b/modules/integration_migrate/src/Plugin/migrate/process/TagToId.php @@ -0,0 +1,32 @@ +id(); + } + return NULL; + } + +} diff --git a/modules/integration_migrate/src/Plugin/migrate/source/IntegrationDocuments.php b/modules/integration_migrate/src/Plugin/migrate/source/IntegrationDocuments.php index 2c51ae6..88c0bd8 100644 --- a/modules/integration_migrate/src/Plugin/migrate/source/IntegrationDocuments.php +++ b/modules/integration_migrate/src/Plugin/migrate/source/IntegrationDocuments.php @@ -29,6 +29,13 @@ class IntegrationDocuments extends SourcePluginBase { */ private $documentsArray = []; + /** + * Contains mapping data. + * + * @var array + */ + private $mappingData; + /** * {@inheritdoc} */ @@ -97,44 +104,62 @@ public function getDocumentType() { /** * {@inheritdoc} + * + * @todo: This does a bit to much at the moment and needs some cleanup to + * avoid unwanted results.. */ public function prepareRow(Row $row) { $language = $row->getSource()['language']; - foreach ($this->getDocument()->getFieldMachineNames() as $field_name) { - $row->setDestinationProperty($field_name, $row->getSource()['processed'] - ->getFieldValue($field_name, $language)); - } - - // @todo: Static metadata, this can go into Document I think.. - $static_metadata = [ - 'nid' => '_id', - 'bundle' => 'type', - 'created' => 'created', - 'changed' => 'changed', - 'status' => 'status', - 'sticky' => 'sticky', - 'default_langcode' => 'default_langcode', - ]; - - foreach ($static_metadata as $destination => $source) { + foreach ($this->getMappingData() as $destination => $source) { if (!is_null($this->getDocument()->getMetadata($source))) { $row->setDestinationProperty($destination, $row->getSource()['processed'] ->getMetadata($source)); + $row->setSourceProperty($destination, $row->getSource()['processed'] + ->getMetadata($source)); } } + // Map the remaining data, but exclude fields with custom mapping. + foreach ($this->getDocument()->getFieldMachineNames() as $field_name) { + $source = $field_name; + $destination = $field_name; + // Exclude already mapped data. + if (array_key_exists($field_name, $this->getMappingData())) { $destination = $this->getMappingData()[$field_name]; } + $row->setDestinationProperty($destination, $row->getSource()['processed'] + ->getFieldValue($source, $language)); + $row->setSourceProperty($destination, $row->getSource()['processed'] + ->getFieldValue($source, $language)); + } + // We need the language property. $row->setDestinationProperty('language', $language); $row->setDestinationProperty('langcode', $language); - $bar = $row->getIdMap(); - $bar['destid2'] = $language; - $row->setIdMap($bar); - return parent::prepareRow($row); } + /** + * Gets the mapping data as an array. + * + * @return array + * The mapping data destination=>source. + */ + private function getMappingData() { + if (empty($this->mappingData)) { + $this->mappingData = [ + 'nid' => '_id', + 'bundle' => 'type', + 'created' => 'created', + 'changed' => 'changed', + 'status' => 'status', + 'sticky' => 'sticky', + 'default_langcode' => 'default_langcode', + ]; + } + return $this->mappingData; + } + /** * {@inheritdoc} */ diff --git a/modules/integration_migrate/tests/modules/integration_migrate_entity/data/10931.json b/modules/integration_migrate/tests/modules/integration_migrate_entity/data/10931.json new file mode 100644 index 0000000..29a2612 --- /dev/null +++ b/modules/integration_migrate/tests/modules/integration_migrate_entity/data/10931.json @@ -0,0 +1,31 @@ +{ + "_id": "10931", + "default_language": "en", + "languages": [ + "en" + ], + "fields": { + "title": { + "en": [ + "Test simple document title" + ] + }, + "tags": { + "en": [ + "Tag 1", + "Tag 2" + ] + }, + "multi_data": { + "en": [ + "List item 1", + "List item 2" + ] + } + }, + "type": "integration_document_entity_test", + "created": "1235583913", + "changed": "1329926433", + "status": "0", + "sticky": "0" +} diff --git a/modules/integration_migrate/tests/src/Kernel/MigrateDocumentEntityTest.php b/modules/integration_migrate/tests/src/Kernel/MigrateDocumentEntityTest.php index 1a26c15..13fd982 100644 --- a/modules/integration_migrate/tests/src/Kernel/MigrateDocumentEntityTest.php +++ b/modules/integration_migrate/tests/src/Kernel/MigrateDocumentEntityTest.php @@ -2,6 +2,11 @@ namespace Drupal\integration_migrate\tests\Kernel; +use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\Core\Language\LanguageInterface; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait; use Drupal\KernelTests\KernelTestBase; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\migrate\MigrateExecutable; @@ -9,12 +14,16 @@ use Drupal\migrate\Plugin\MigrationInterface; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; +use Drupal\taxonomy\Entity\Term; +use Drupal\taxonomy\Entity\Vocabulary; /** * Tests Migration of Documents using Integration. */ class MigrateDocumentEntityTest extends KernelTestBase { + use EntityReferenceTestTrait; + /** * Modules to enable. * @@ -27,9 +36,12 @@ class MigrateDocumentEntityTest extends KernelTestBase { 'integration', 'integration_migrate', 'language', + 'taxonomy', 'content_translation', + 'integration_migrate_entity', 'node', 'field', + 'text', 'user', ]; @@ -39,9 +51,10 @@ class MigrateDocumentEntityTest extends KernelTestBase { public function setUp() { parent::setUp(); $this->installSchema('system', ['sequences']); - $this->installSchema('node', array('node_access')); + $this->installSchema('node', ['node_access']); $this->installEntitySchema('user'); $this->installEntitySchema('node'); + $this->installEntitySchema('taxonomy_term'); // Create some languages. ConfigurableLanguage::createFromLangcode('en')->save(); @@ -56,7 +69,6 @@ public function setUp() { /** @var \Drupal\content_translation\ContentTranslationManagerInterface $content_translation_manager */ $content_translation_manager = \Drupal::service('content_translation.manager'); - $content_translation_manager->setEnabled('node', 'integration_document_entity_test', TRUE); } @@ -64,8 +76,6 @@ public function setUp() { * Tests document import using migrate. */ public function testSimpleDocumentImport() { - $this->enableModules(['integration_migrate_entity']); - $definition = [ 'source' => [ 'plugin' => 'integration_documents', @@ -90,14 +100,14 @@ public function testSimpleDocumentImport() { $this->assertNotNull($node); // Check field data. - $this->assertEquals($node->getTitle(), 'Test simple document title'); + $this->assertEquals('Test simple document title', $node->getTitle()); // Check metadata. - $this->assertEquals($node->getType(), 'integration_document_entity_test'); - $this->assertEquals($node->getCreatedTime(), '1235583913'); - $this->assertEquals($node->getChangedTime(), '1329926433'); - $this->assertEquals($node->isPublished(), FALSE); - $this->assertEquals($node->isSticky(), FALSE); + $this->assertEquals('integration_document_entity_test', $node->getType()); + $this->assertEquals('1235583913', $node->getCreatedTime()); + $this->assertEquals('1329926433', $node->getChangedTime()); + $this->assertEquals(FALSE, $node->isPublished()); + $this->assertEquals(FALSE, $node->isSticky()); } /** @@ -107,8 +117,6 @@ public function testSimpleDocumentImport() { * ensure data is stable. */ public function testTranslatedDocumentImport() { - $this->enableModules(['integration_migrate_entity']); - $definition = [ 'source' => [ 'plugin' => 'integration_documents', @@ -137,25 +145,23 @@ public function testTranslatedDocumentImport() { $this->assertNotEmpty($node_translated); // Check en field data. - $this->assertEquals($node->getTitle(), 'Test multilingual document title'); + $this->assertEquals('Test multilingual document title', $node->getTitle()); // Check fr field data. - $this->assertEquals($node_translated->getTitle(), 'Teste le titre du document multilingue'); + $this->assertEquals('Teste le titre du document multilingue', $node_translated->getTitle()); // Check metadata. - $this->assertEquals($node->getType(), 'integration_document_entity_test'); - $this->assertEquals($node->getCreatedTime(), '1235583913'); - $this->assertEquals($node->getChangedTime(), '1329926433'); - $this->assertEquals($node->isPublished(), FALSE); - $this->assertEquals($node->isSticky(), FALSE); + $this->assertEquals('integration_document_entity_test', $node->getType()); + $this->assertEquals('1235583913', $node->getCreatedTime()); + $this->assertEquals('1329926433', $node->getChangedTime()); + $this->assertEquals(FALSE, $node->isPublished()); + $this->assertEquals(FALSE, $node->isSticky()); } /** * Tests migrating a folder instead of a specific file. */ public function testFolderDocumentImport() { - $this->enableModules(['integration_migrate_entity']); - $definition = [ 'source' => [ 'plugin' => 'integration_documents', @@ -177,11 +183,129 @@ public function testFolderDocumentImport() { $node1 = Node::load(10861); // Check that we can load the node. $this->assertNotNull($node1); - $this->assertEquals($node1->getTitle(), 'Test simple document title'); + $this->assertEquals('Test simple document title', $node1->getTitle()); /** @var \Drupal\node\NodeInterface $node2 */ $node2 = Node::load(101337); // Check that we can load the node. $this->assertNotNull($node2); - $this->assertEquals($node2->getTitle(), 'Test multilingual document title'); + $this->assertEquals('Test multilingual document title', $node2->getTitle()); + } + + /** + * Tests that we can process data so that we can still map taxonomy to their + * respective database id. + */ + public function testMappingTaxonomyDocumentImport() { + // Create a vocabulary named "Tags". + $vocabulary = Vocabulary::create([ + 'name' => 'Tags', + 'vid' => 'tags', + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ]); + $vocabulary->save(); + + Term::create([ + 'name' => 'Tag 1', + 'vid' => 'tags', + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ])->save(); + Term::create([ + 'name' => 'Tag 2', + 'vid' => 'tags', + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ])->save(); + + $handler_settings = [ + 'target_bundles' => [ + $vocabulary->id() => $vocabulary->id(), + ], + // Enable auto-create. + 'auto_create' => TRUE, + ]; + $this->createEntityReferenceField('node', 'integration_document_entity_test', 'field_tags', 'Tags', 'taxonomy_term', 'default', $handler_settings, 10); + + $definition = [ + 'source' => [ + 'plugin' => 'integration_documents', + 'data_path' => drupal_get_path('module', 'integration_migrate_entity') . '/data/10931.json', + ], + 'process' => [ + 'field_tags' => [ + 'plugin' => 'tag_to_id', + 'source' => 'tags', + ], + ], + 'destination' => [ + 'plugin' => 'integration_document', + ], + ]; + + $migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($definition); + $executable = new MigrateExecutable($migration, new MigrateMessage()); + + $result = $executable->import(); + $this->assertEquals(MigrationInterface::RESULT_COMPLETED, $result); + + /** @var \Drupal\node\NodeInterface $node */ + $node = Node::load(10931); + $this->assertNotNull($node); + + // Load the tags. + $tags = $node->get('field_tags')->referencedEntities(); + + // Check that the terms are referenced. + $this->assertEquals('Tag 1', $tags[0]->getName()); + $this->assertEquals('Tag 2', $tags[1]->getName()); } + + /** + * Tests that we can process data with multiple rows using mapping. + */ + public function testMappingMultiDataDocumentImport() { + + FieldStorageConfig::create(array( + 'field_name' => 'field_multi_data', + 'entity_type' => 'node', + 'type' => 'text' + )) + ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) + ->save(); + + FieldConfig::create(array( + 'field_name' => 'field_multi_data', + 'entity_type' => 'node', + 'bundle' => 'integration_document_entity_test', + ))->save(); + + $definition = [ + 'source' => [ + 'plugin' => 'integration_documents', + 'data_path' => drupal_get_path('module', 'integration_migrate_entity') . '/data/10931.json', + ], + 'process' => [ + 'field_multi_data' => 'multi_data', + ], + 'destination' => [ + 'plugin' => 'integration_document', + ], + ]; + + $migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($definition); + $executable = new MigrateExecutable($migration, new MigrateMessage()); + + $result = $executable->import(); + $this->assertEquals(MigrationInterface::RESULT_COMPLETED, $result); + + /** @var \Drupal\node\NodeInterface $node */ + $node = Node::load(10931); + $this->assertNotNull($node); + + // Check data in field_multi_data. + $field_multi_data = $node->get('field_multi_data'); + $this->assertEquals('List item 1', $field_multi_data->get(0)->getValue()['value']); + $this->assertEquals('List item 2', $field_multi_data->get(1)->getValue()['value']); + } + }