<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260325142749 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE contacts DROP FOREIGN KEY FK_44F066DA72F5A1AA');
$this->addSql('ALTER TABLE contacts ADD CONSTRAINT FK_44F066DA72F5A1AA_TMP FOREIGN KEY (channel_id) REFERENCES channel_channels (id) ON DELETE CASCADE');
$this->addSql('CREATE TABLE channel_contacts (channel_id VARCHAR(36) NOT NULL, contact_id VARCHAR(36) NOT NULL, INDEX IDX_44F066DA72F5A1AA (channel_id), INDEX IDX_44F066DAE7A1254A (contact_id), PRIMARY KEY(channel_id, contact_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE channel_contacts ADD CONSTRAINT FK_44F066DA72F5A1AA FOREIGN KEY (channel_id) REFERENCES channel_channels (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE channel_contacts ADD CONSTRAINT FK_44F066DAE7A1254A FOREIGN KEY (contact_id) REFERENCES contacts (id) ON DELETE CASCADE');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE channel_contacts DROP FOREIGN KEY FK_44F066DA72F5A1AA');
$this->addSql('ALTER TABLE channel_contacts DROP FOREIGN KEY FK_44F066DAE7A1254A');
$this->addSql('DROP TABLE channel_contacts');
$this->addSql('ALTER TABLE contacts DROP FOREIGN KEY FK_44F066DA72F5A1AA_TMP');
$this->addSql('ALTER TABLE contacts ADD CONSTRAINT FK_44F066DA72F5A1AA FOREIGN KEY (channel_id) REFERENCES channel_channels (id) ON DELETE CASCADE');
}
public function postUp(Schema $schema): void
{
// Check duplicates "email + channel_id"
$duplicates = $this->connection->fetchAllAssociative("
SELECT email, MIN(id) as keep_id, GROUP_CONCAT(id) as all_ids, GROUP_CONCAT(channel_id) as all_channel_ids
FROM contacts
GROUP BY email
HAVING COUNT(*) > 1
");
foreach ($duplicates as $group) {
$keepId = $group['keep_id'];
$allIds = explode(',', $group['all_ids']);
$allChannelIds = explode(',', $group['all_channel_ids']);
$idsToChannelIds = array_combine($allIds, $allChannelIds);
$duplicateIds = array_filter($allIds, fn($id) => $id !== $keepId);
foreach ($duplicateIds as $duplicateId) {
$duplicateChannelId = $idsToChannelIds[$duplicateId];
$this->connection->executeStatement(
'INSERT IGNORE INTO channel_contacts (channel_id, contact_id) VALUES (?, ?)',
[$duplicateChannelId, $keepId]
);
$this->connection->executeStatement(
'UPDATE channel_positioning_test_attempts SET prospect_id = ? WHERE prospect_id = ?',
[$keepId, $duplicateId]
);
$this->connection->executeStatement(
'DELETE FROM contacts WHERE id = ?',
[$duplicateId]
);
}
}
$contacts = $this->connection->fetchAllAssociative('SELECT id, channel_id FROM contacts');
foreach ($contacts as $contact) {
$contactId = $contact['id'];
$channelId = $contact['channel_id'];
$this->connection->executeStatement(
'INSERT IGNORE INTO channel_contacts (channel_id, contact_id) VALUES (?, ?)',
[$channelId, $contactId]
);
}
}
}