Spaces:
No application file
No application file
File size: 3,460 Bytes
d2897cd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<?php
declare(strict_types=1);
namespace Mautic\LeadBundle\Deduplicate;
use Mautic\LeadBundle\Deduplicate\Exception\SameContactException;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\LeadBundle\Entity\LeadRepository;
use Mautic\LeadBundle\Model\FieldModel;
class ContactDeduper
{
use DeduperTrait;
public function __construct(
FieldModel $fieldModel,
private ContactMerger $contactMerger,
private LeadRepository $leadRepository
) {
$this->fieldModel = $fieldModel;
}
/**
* @return array<string,string>
*/
public function getUniqueFields(string $object): array
{
return $this->fieldModel->getUniqueIdentifierFields(['object' => $object]);
}
/**
* @param string[] $uniqueFieldAliases
*/
public function countDuplicatedContacts(array $uniqueFieldAliases): int
{
return $this->leadRepository->getContactCountWithDuplicateValues($uniqueFieldAliases);
}
/**
* @param string[] $uniqueFieldAliases
*
* @return string[]
*/
public function getDuplicateContactIds(array $uniqueFieldAliases): array
{
return $this->leadRepository->getDuplicatedContactIds($uniqueFieldAliases);
}
/**
* @param string[]|int[] $contactIds
*
* @return Lead[]
*/
public function getContactsByIds(array $contactIds): array
{
return $this->leadRepository->getEntities(['ids' => $contactIds, 'ignore_paginator' => false]);
}
/**
* @param Lead[] $contacts
*/
public function deduplicateContactBatch(array $contacts, bool $newerIntoOlder, callable $onContactProcessed = null): void
{
foreach ($contacts as $contact) {
$duplicates = $this->checkForDuplicateContacts($contact->getProfileFields(), $newerIntoOlder);
$this->mergeContacts($duplicates);
$this->detachContacts($duplicates);
if ($onContactProcessed) {
$onContactProcessed($contact);
}
}
}
/**
* To save RAM.
*
* @param Lead[] $contacts
*/
public function detachContacts(array $contacts): void
{
$this->leadRepository->detachEntities($contacts);
}
/**
* @param Lead[] $duplicates
*/
public function mergeContacts(array $duplicates): void
{
if (empty($duplicates)) {
return;
}
$loser = reset($duplicates);
while ($winner = next($duplicates)) {
try {
$this->contactMerger->merge($winner, $loser);
} catch (SameContactException) {
}
$loser = $winner;
}
}
/**
* @return Lead[]
*/
public function checkForDuplicateContacts(array $queryFields, bool $mergeNewerIntoOlder = false)
{
$duplicates = [];
$uniqueData = $this->getUniqueData($queryFields);
if (!empty($uniqueData)) {
$duplicates = $this->leadRepository->getLeadsByUniqueFields($uniqueData);
// By default, duplicates are ordered by newest first
if (!$mergeNewerIntoOlder) {
// Reverse the array so that oldest are on "top" in order to merge oldest into the next until they all have been merged into the
// the newest record
$duplicates = array_reverse($duplicates);
}
}
return $duplicates;
}
}
|