diff --git a/src/DefaultContentManager.php b/src/DefaultContentManager.php index 6160c48..17cfe39 100644 --- a/src/DefaultContentManager.php +++ b/src/DefaultContentManager.php @@ -5,6 +5,7 @@ namespace Drupal\default_content; use Drupal\Component\Graph\Graph; use Drupal\Component\Render\FormattableMarkup; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Extension\InfoParserInterface; @@ -219,15 +220,27 @@ class DefaultContentManager implements DefaultContentManagerInterface { $contents = $this->parseFile($file); $class = $definition['serialization_class']; $entity = $this->serializer->deserialize($contents, $class, 'hal_json', array('request_method' => 'POST')); - // Unset entity keys to avoid collisions. UUID will conflict will - // alert us to any true collision. - $entity_type = $this->entityManager->getDefinition($entity_type_id); - $keys = $entity_type->getKeys(); - unset($entity->{$keys['id']}); - if (isset($keys['revision'])) { - unset($entity->{$keys['revision']}); + if ($entity->validate()->count()) { + // Try to resolve validation errors by unsetting entity keys. + $entity_type = $this->entityManager->getDefinition($entity_type_id); + $keys = $entity_type->getKeys(); + unset($entity->{$keys['id']}); + if (isset($keys['revision'])) { + unset($entity->{$keys['revision']}); + } + if ($entity->validate()->count()) { + // Pass on this entity if we still have validation errors. + // Should we alert someone about this? + continue; + } + } + try { + $entity->save(); + } + catch (EntityStorageException $e) { + // What do we do with this? + continue; } - $entity->save(); $created[$entity->uuid()] = $entity; } } diff --git a/tests/modules/default_content_test/content/user/user2.json b/tests/modules/default_content_test/content/user/user2.json new file mode 100644 index 0000000..a0e7abf --- /dev/null +++ b/tests/modules/default_content_test/content/user/user2.json @@ -0,0 +1,83 @@ +{ + "_links": { + "self": { + "href": "http://dev-sprouts.pantheonsite.io/user/2" + }, + "type": { + "href": "http://drupal.org/rest/type/user/user" + } + }, + "uid": [ + { + "value": "2" + } + ], + "uuid": [ + { + "value": "e224a97e-1899-48d9-995e-14820df45400" + } + ], + "langcode": [ + { + "value": "en", + "lang": "en" + } + ], + "preferred_langcode": [ + { + "value": "en" + } + ], + "name": [ + { + "value": "Administrator" + } + ], + "mail": [ + { + "value": "info@example.com" + } + ], + "timezone": [ + { + "value": "America/New_York" + } + ], + "status": [ + { + "value": "1" + } + ], + "created": [ + { + "value": "1484161522" + } + ], + "changed": [ + { + "value": "1484161644", + "lang": "en" + } + ], + "access": [ + { + "value": "0" + } + ], + "login": [ + { + "value": "0" + } + ], + "roles": [ + { + "target_id": "administrator" + } + ], + "default_langcode": [ + { + "value": "1", + "lang": "en" + } + ] +} \ No newline at end of file diff --git a/tests/modules/default_content_test/content/user/user2fail.json b/tests/modules/default_content_test/content/user/user2fail.json new file mode 100644 index 0000000..f55f1d3 --- /dev/null +++ b/tests/modules/default_content_test/content/user/user2fail.json @@ -0,0 +1,83 @@ +{ + "_links": { + "self": { + "href": "http://dev-sprouts.pantheonsite.io/user/2" + }, + "type": { + "href": "http://drupal.org/rest/type/user/user" + } + }, + "uid": [ + { + "value": "2" + } + ], + "uuid": [ + { + "value": "foo4a97e-1899-48d9-995e-14820df45400" + } + ], + "langcode": [ + { + "value": "en", + "lang": "en" + } + ], + "preferred_langcode": [ + { + "value": "en" + } + ], + "name": [ + { + "value": "EmailConflict" + } + ], + "mail": [ + { + "value": "info@example.com" + } + ], + "timezone": [ + { + "value": "America/New_York" + } + ], + "status": [ + { + "value": "1" + } + ], + "created": [ + { + "value": "1484161522" + } + ], + "changed": [ + { + "value": "1484161644", + "lang": "en" + } + ], + "access": [ + { + "value": "0" + } + ], + "login": [ + { + "value": "0" + } + ], + "roles": [ + { + "target_id": "administrator" + } + ], + "default_langcode": [ + { + "value": "1", + "lang": "en" + } + ] +} \ No newline at end of file diff --git a/tests/src/Functional/DefaultContentTest.php b/tests/src/Functional/DefaultContentTest.php index eadf73f..ea5db2f 100644 --- a/tests/src/Functional/DefaultContentTest.php +++ b/tests/src/Functional/DefaultContentTest.php @@ -31,14 +31,15 @@ class DefaultContentTest extends BrowserTestBase { parent::setUp(); $this->createContentType(array('type' => 'page')); $this->createContentType(array('type' => 'article')); + // Login as admin. + $this->account = $this->drupalCreateUser([], 'DefaultContentAdmin', FALSE); + $this->drupalLogin($this->account); } /** * Test importing default content. */ public function testImport() { - // Login as admin. - $this->drupalLogin($this->drupalCreateUser(array_keys(\Drupal::moduleHandler()->invokeAll(('permission'))))); // Enable the module and import the content. \Drupal::service('module_installer')->install(array('default_content_test'), TRUE); $this->rebuildContainer(); @@ -57,8 +58,6 @@ class DefaultContentTest extends BrowserTestBase { * Test stripping entity ids during import. */ public function testImportWithEntityIdConflict() { - $this->drupalLogin($this->drupalCreateUser(array_keys(\Drupal::moduleHandler()->invokeAll(('permission'))))); - // Create entities with known-conflicting ids. $conflict_node = $this->createNode([ 'title' => 'Node with conflicting nid', @@ -76,12 +75,25 @@ class DefaultContentTest extends BrowserTestBase { // Enable the module and import the content. \Drupal::service('module_installer')->install(array('default_content_test'), TRUE); $this->rebuildContainer(); + + // Check conflicting node nid. $node = $this->getNodeByTitle('Imported node'); $this->assertNotEquals($node->id(), $conflict_node->id()); $this->assertNotEquals($node->getRevisionId(), $conflict_node->getRevisionId()); + + // Check conflicting term tid. $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties(['name' => 'A tag']); $term = reset($terms); $this->assertNotEquals($term->id(), $conflict_term->id()); + + // Check conflicting user uid. + $users = \Drupal::entityTypeManager()->getStorage('user')->loadByProperties(['name' => 'Administrator']); + $user = reset($users); + $this->assertNotEquals($user->id(), $this->account->id()); + + // Confirm user with conflicting email was not imported. + $users = \Drupal::entityTypeManager()->getStorage('user')->loadByProperties(['name' => 'EmailConflict']); + $this->assertEmpty($users); } }