New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Command to deduplicate contacts #5344
Command to deduplicate contacts #5344
Conversation
+1 works well. Tentative approval pending UT's |
works properly for me |
789cf21
to
9ab8020
Compare
@alanhartless .... 2.12.0 fix duplicating contacts on import .... this pull will be released on 2.12.0 too? Thanks ;) |
I need to use this, I have a bunch of duplicate contacts and am looking for a safe way to merge them 2.12 came out already but this didn't make it in? How can I use this now? I must create a fork or is there another way? |
123476f
to
5ed1e32
Compare
21bb42f
to
f103a5b
Compare
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
/** @var ContactDeduper $deduper */ | ||
$deduper = $this->getContainer()->get('mautic.lead.deduper'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use DI for new commands?
use Symfony\Component\Console\Input\InputOption; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
class DedupCommand extends ModeratedCommand |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the dedup
real word in English? I think DeduplicateCommand
would be a better name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably more slang but I can rename it.
/** | ||
* @var ContactMerger | ||
*/ | ||
private $merger; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why not to use $contactMerger
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason why not. I'll change it.
/** | ||
* @var LeadRepository | ||
*/ | ||
private $repository; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$leadRepository
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason why not. I'll change it.
|
||
namespace Mautic\LeadBundle\Exception; | ||
|
||
class ValueNotMergeable extends \Exception |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be ValueNotMergeableException
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*/ | ||
public function __construct($newerValue, $olderValue) | ||
{ | ||
parent::__construct(var_export($newerValue, true).' / '.var_export($olderValue, true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is var_export here? Should be a comment here I think, if there is a real reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to add in the message what the value actually was. $newerValue can be anything so var_export converts it to a string for the exception message.
* | ||
* @return Lead | ||
*/ | ||
public function mergeLeads(Lead $lead, Lead $lead2, $autoMode = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this change here? I think this method just should call the new method, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was relocated from elsewhere in the class. But there is a circular dependency if I use the new service here. Will have to create some kind of legacy class just to get around that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to address this by passing the container to a legacy class to keep from having the circular dependency. Will likely need to leverage this class for some other methods in the LeadModel to remove more deprecated code/circular dependencies. I want to get rid of checkForDuplicateContact as well and use the ContactDeduper class instead.
bdc07ef
to
3a7151a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks nice. Will test it. Just found minor issues in the doc blocks.
<?php | ||
|
||
/* | ||
* @copyright 2017 Mautic Contributors. All rights reserved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should read 2018. Also check other file annotations.
|
||
/* | ||
* @copyright 2017 Mautic Contributors. All rights reserved | ||
* @author Mautic, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be Inc, or should it? Also check other file annotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well technically it is Mautic, Inc contributing this code. So I think this is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want every company/individual who creates/modifies the code to add itself as the author? It says "Mautic" on all files I randomly checked. Maybe @dbhurley could way in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just saw Mautic, Inc. on another file from 2014. So if that's not new, let's ignore this discussion.
* @param LeadModel $leadModel | ||
* @param MergeRecordRepository $repo | ||
* @param LoggerInterface $logger | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dispatcher param is missing in the docblock
<?php | ||
|
||
/* | ||
* @copyright 2017 Mautic Contributors. All rights reserved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to be PITA, but could you check all the file annotations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I technically wrote these files in 2017 :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works fine for me. Thanks Alan!
Description:
This PR adds a command
php app/console mautic:contacts:dedup
to find contacts with the same unique identifiers and merge them. By default, the records are merged from oldest into newest but that can be changed with the flag--newest-into-oldest
.Regardless of which record is merged into which, the latest modified record's custom field data is used (except where it is empty as we will error on the side of not completely losing data). Also the latest last active date is preserved and the oldest date identified date.
Contacts with conflicting unique identifiers when there are more than one unique identifier are not merged.
Steps to test this PR:
List deprecations along with the new alternative: