diff --git a/crm/src/Plugin/collect/Processor/ContactMatcher.php b/crm/src/Plugin/collect/Processor/ContactMatcher.php index cdf714b..0d02f17 100644 --- a/crm/src/Plugin/collect/Processor/ContactMatcher.php +++ b/crm/src/Plugin/collect/Processor/ContactMatcher.php @@ -85,7 +85,7 @@ class ContactMatcher extends ProcessorBase { // Update the existing contact or save a new one. if (!empty($existing_contact)) { - $this->updateContact($existing_contact, $contact_values); + $existing_contact = $this->updateContact($existing_contact, $template_contact, array_keys($contact_values)); } else { $existing_contact = $this->saveNewContact($template_contact); @@ -174,8 +174,8 @@ class ContactMatcher extends ProcessorBase { /** @var \Drupal\crm_core_match\Matcher\MatcherConfigInterface $matcher */ $matcher = $this->entityManager->getStorage('crm_core_match')->load($this->getConfigurationItem('matcher')); if ($matches = $matcher->match($template_contact)) { - return $this->entityManager->getStorage('crm_core_contact') - ->load(reset($matches)); + // @todo: Handle the case if there are multiple matches. + return $this->entityManager->getStorage('crm_core_contact')->load(reset($matches)); } return NULL; @@ -186,26 +186,49 @@ class ContactMatcher extends ProcessorBase { * * @param \Drupal\crm_core_contact\ContactInterface $existing_contact * The existing contact. - * @param array $new_values - * Associative array of new values for some fields, keyed by field names. + * @param \Drupal\crm_core_contact\ContactInterface $template_contact + * The template contact containing new values. + * @param array $updated_fields + * Associative array of updated fields. + * + * @return \Drupal\crm_core_contact\ContactInterface + * The updated contact. */ - protected function updateContact(ContactInterface $existing_contact, array $new_values) { - $has_changed = FALSE; - foreach ($new_values as $field_name => $value) { - $current_value = $existing_contact->get($field_name)->getValue(); - // Append user URI if unique. + protected function updateContact(ContactInterface $existing_contact, ContactInterface $template_contact, array $updated_fields) { + foreach ($updated_fields as $field_name) { if ($field_name == 'user_uri') { - $value = array_unique(array_merge($current_value, $value), SORT_REGULAR); - } - // Only change field value and trigger new revision if value has changed. - if ($value != $current_value) { - $existing_contact->set($field_name, $value); - $has_changed = TRUE; + $this->updateUserUri($existing_contact, $template_contact); + continue; } + $existing_contact->{$field_name} = $template_contact->get($field_name); } - if ($has_changed) { - $existing_contact->setNewRevision(); - $existing_contact->save(); + + $existing_contact->save(); + + return $existing_contact; + } + + /** + * Updates a user URI field of an existing contact. + * + * @param \Drupal\crm_core_contact\ContactInterface $existing_contact + * The existing contact. + * @param \Drupal\crm_core_contact\ContactInterface $template_contact + * The template contact. + */ + protected function updateUserUri(ContactInterface $existing_contact, ContactInterface $template_contact) { + // Get existing user URIs. + $user_uris = $existing_contact->get('user_uri'); + $matched_uris = $template_contact->get('user_uri'); + + // Loop over matched and existing user URIs and update existing URIs with + // new ones. + foreach ($matched_uris as $matched_uri) { + foreach ($user_uris as $user_uri) { + if ($matched_uri->getValue() != $user_uri->getValue()) { + $user_uris->appendItem($matched_uri); + } + } } } diff --git a/crm/tests/src/Kernel/MailContactMatcherTest.php b/crm/tests/src/Kernel/MailContactMatcherTest.php index ae44cf5..99066d3 100644 --- a/crm/tests/src/Kernel/MailContactMatcherTest.php +++ b/crm/tests/src/Kernel/MailContactMatcherTest.php @@ -96,6 +96,11 @@ class MailContactMatcherTest extends KernelTestBase { // Assert returned contact has a correct name. $this->assertEquals($contact->get('name')->given, 'Nancy'); + + // Assert there are no new contacts created after repeating the processing. + $context = []; + $mail_contact_matcher->process($collect_type_data_provider->getTypedData($container), $context); + $this->assertEquals(1, count($context['contacts']['default']), 'No new contacts.'); } }