From 5a424771fda229886ef0e04188c239f1714b777e Mon Sep 17 00:00:00 2001 From: Marc Koch Date: Mon, 31 Mar 2025 17:58:01 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20include=20email=5Fid=20in=20group?= =?UTF-8?q?=20membership?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Civi/Mailinglistsync/ADGroupMailingList.php | 13 ++-- .../Exceptions/MailinglistException.php | 1 + Civi/Mailinglistsync/GroupMailingList.php | 12 ++-- Civi/Mailinglistsync/MailingListRecipient.php | 71 ++++++++++++++++++- api/v3/Mailinglistsync/Mlmmjsync.php | 2 +- 5 files changed, 86 insertions(+), 13 deletions(-) diff --git a/Civi/Mailinglistsync/ADGroupMailingList.php b/Civi/Mailinglistsync/ADGroupMailingList.php index e1eaf30..ae72c92 100644 --- a/Civi/Mailinglistsync/ADGroupMailingList.php +++ b/Civi/Mailinglistsync/ADGroupMailingList.php @@ -340,8 +340,7 @@ class ADGroupMailingList extends GroupMailingList { * @throws \Civi\Mailinglistsync\Exceptions\MailinglistException */ public - static function syncContacts($recipients - ): array { + static function syncContacts($recipients): array { $results = []; foreach ($recipients as $contact) { @@ -471,12 +470,13 @@ class ADGroupMailingList extends GroupMailingList { * @return array|array[] */ private - function addRecipient(int $contactId - ): array { + function addRecipient(int $contactId): array { $result = []; // Add the contact to the group try { - $this->addContactToGroup($contactId); + $contactEmail = MailingListRecipient::getContactById($contactId) + ->getEmailId(self::LOCATION_TYPE); + $this->addContactToGroup($contactId, $contactEmail); $result['added'] = TRUE; } catch (MailinglistException $e) { @@ -496,8 +496,7 @@ class ADGroupMailingList extends GroupMailingList { * @return array */ public - function removeRecipient(MailingListRecipient $recipient - ): array { + function removeRecipient(MailingListRecipient $recipient): array { $result = [ 'sid' => $recipient->getSid(), 'contact_id' => $recipient->getContactId(), diff --git a/Civi/Mailinglistsync/Exceptions/MailinglistException.php b/Civi/Mailinglistsync/Exceptions/MailinglistException.php index 750ddec..5e2fcf5 100644 --- a/Civi/Mailinglistsync/Exceptions/MailinglistException.php +++ b/Civi/Mailinglistsync/Exceptions/MailinglistException.php @@ -41,5 +41,6 @@ class MailinglistException extends BaseException { public const ERROR_CODE_UPDATE_MAILING_LIST_FAILED = 'update_mailing_list_failed'; public const ERROR_CODE_UPDATE_SUBSCRIBERS_FAILED = 'update_subscribers_failed'; public const ERROR_CODE_DELETE_MAILING_LIST_FAILED = 'delete_mailing_list_failed'; + public const ERROR_CODE_GET_EMAIL_ID_FAILED = 'get_email_id_failed'; } diff --git a/Civi/Mailinglistsync/GroupMailingList.php b/Civi/Mailinglistsync/GroupMailingList.php index a1af0d7..d51e001 100644 --- a/Civi/Mailinglistsync/GroupMailingList.php +++ b/Civi/Mailinglistsync/GroupMailingList.php @@ -172,16 +172,20 @@ class GroupMailingList extends BaseMailingList { * Add a contact to this mailing lists related group. * * @param int $contactId + * @param ?int $contactEmailId * * @return void * @throws \Civi\Mailinglistsync\Exceptions\MailinglistException */ - protected function addContactToGroup(int $contactId): void { + protected function addContactToGroup(int $contactId, int $contactEmailId = NULL): void { try { - \Civi\Api4\GroupContact::create() + $query = \Civi\Api4\GroupContact::create() ->addValue('contact_id', $contactId) - ->addValue('group_id', $this->group['id']) - ->execute(); + ->addValue('group_id', $this->group['id']); + if ($contactEmailId) { + $query->addValue('email_id', $contactEmailId); + } + $query->execute(); } catch (\Exception $e) { if ($e->getMessage() === 'DB Error: already exists') { diff --git a/Civi/Mailinglistsync/MailingListRecipient.php b/Civi/Mailinglistsync/MailingListRecipient.php index fcfe6d2..0241c26 100644 --- a/Civi/Mailinglistsync/MailingListRecipient.php +++ b/Civi/Mailinglistsync/MailingListRecipient.php @@ -128,7 +128,7 @@ class MailingListRecipient { * @return MailingListRecipient * @throws \Civi\Mailinglistsync\Exceptions\MailinglistException */ - public static function getContactIdEmail(string $email): MailingListRecipient { + public static function getContactByEmail(string $email): MailingListRecipient { try { $recipientData = Contact::get() ->addSelect('id', 'first_name', 'last_name', 'email.email', 'Active_Directory.SID') @@ -163,6 +163,49 @@ class MailingListRecipient { return $recipient; } + /** + * Get a recipient by its id. + * + * @param int $id + * + * @return MailingListRecipient + * @throws \Civi\Mailinglistsync\Exceptions\MailinglistException + */ + public static function getContactById(int $id): MailingListRecipient { + try { + $recipientData = Contact::get() + ->addSelect('id', 'first_name', 'last_name', 'email.email', 'Active_Directory.SID') + ->addJoin('Email AS email', 'LEFT', ['id', '=', 'email.contact_id']) + ->addWhere('id', '=', $id) + ->addGroupBy('id') + ->execute() + ->first(); + } + catch (\Exception $e) { + throw new MailinglistException( + "Could not get recipient by id '{$id}': {$e->getMessage()}", + MailinglistException::ERROR_CODE_GET_RECIPIENTS_FAILED + ); + } + + try { + $recipient = new MailingListRecipient( + sid: $recipientData['Active_Directory.SID'], + contact_id: $recipientData['id'], + first_name: $recipientData['first_name'], + last_name: $recipientData['last_name'], + email: $recipientData['email.email'], + ); + } catch (\Exception $e) { + throw new MailinglistException( + "Could not create recipient object for contact with id '{$recipientData['id']}': {$e->getMessage()}", + MailinglistException::ERROR_CODE_GET_RECIPIENTS_FAILED + ); + } + + return $recipient; + } + /** * Get a list of group mailing lists the contact is subscribed to. * @@ -307,6 +350,32 @@ class MailingListRecipient { return $this->email; } + /** + * Get the email id. + * + * @param string $locationType + * + * @return int|NULL + * @throws \Civi\Mailinglistsync\Exceptions\MailinglistException + */ + public function getEmailId(string $locationType): ?int { + try { + return \Civi\Api4\Email::get() + ->addSelect('id') + ->addWhere('contact_id', '=', $this->getContactId()) + ->addWhere('email', '=', $this->email) + ->addWhere('location_type_id:name', '=', $locationType) + ->execute() + ->first()['id'] ?? NULL; + } + catch (\Exception $e) { + throw new MailinglistException( + "Failed to get email id: {$e->getMessage()}", + MailinglistException::ERROR_CODE_GET_EMAIL_ID_FAILED, + ); + } + } + /** * Get the SID of the contact. * diff --git a/api/v3/Mailinglistsync/Mlmmjsync.php b/api/v3/Mailinglistsync/Mlmmjsync.php index 8f08ec2..6eca4e0 100644 --- a/api/v3/Mailinglistsync/Mlmmjsync.php +++ b/api/v3/Mailinglistsync/Mlmmjsync.php @@ -110,7 +110,7 @@ function civicrm_api3_mailinglistsync_Mlmmjsync($params) { $mailingListsToSync[$event->getId()] = $event; } foreach ($emails as $email) { - $recipient = MailingListRecipient::getContactIdEmail($email); + $recipient = MailingListRecipient::getContactByEmail($email); $emailGroups = $recipient->getMailingLists(); $emailEvents = $recipient->getEventMailingLists(); foreach ($emailGroups as $group) {