252 lines
7 KiB
PHP
252 lines
7 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Civi\Mailinglistsync;
|
|
|
|
use Civi\Api4\Contact;
|
|
use Civi\Api4\Group;
|
|
use Civi\Mailinglistsync\Exceptions\MailinglistException;
|
|
|
|
class GroupMailingList extends BaseMailingList {
|
|
|
|
public const CUSTOM_GROUP_NAME = 'Group_Mailing_List';
|
|
|
|
public const LOCATION_TYPE = 'Mailing_List_Address';
|
|
|
|
protected const RELATED_CLASS = Group::class;
|
|
protected const RELATED_TYPE = 'group';
|
|
|
|
protected array $group;
|
|
|
|
/**
|
|
* Returns the related group.
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function getEntity(): array {
|
|
return $this->group;
|
|
}
|
|
|
|
/**
|
|
* Create a new GroupMailingList.
|
|
*
|
|
* @param string $title
|
|
* @param ?string $description
|
|
* @param string $email
|
|
* @param string|null $sid
|
|
*
|
|
* @return \Civi\Mailinglistsync\GroupMailingList
|
|
* @throws \Civi\Mailinglistsync\Exceptions\MailinglistException
|
|
*/
|
|
public static function createGroup(
|
|
string $title,
|
|
string $email,
|
|
string $description = NULL,
|
|
string $sid = NULL
|
|
): self {
|
|
try {
|
|
$request = \Civi\Api4\Group::create()
|
|
->addValue('title', $title)
|
|
->addValue(static::CUSTOM_GROUP_NAME . '.E_mail_address', $email)
|
|
->addValue(static::CUSTOM_GROUP_NAME . '.Enable_mailing_list', 1)
|
|
->addValue('is_active', 1);
|
|
|
|
// Add the description if it's not empty
|
|
if (!empty($description)) {
|
|
$request->addValue('description', $description);
|
|
}
|
|
|
|
// If the group is an AD group, add the AD SID
|
|
if (!empty($sid)) {
|
|
$request->addValue(static::CUSTOM_GROUP_NAME . '.Active_Directory_SID', $sid);
|
|
}
|
|
$group = $request->execute()->first();
|
|
return empty($sid) ? new self($group): new ADGroupMailingList($group);
|
|
}
|
|
catch (\Exception $e) {
|
|
throw new MailinglistException(
|
|
"Could not create group\n$e",
|
|
MailinglistException::ERROR_CODE_GROUP_CREATION_FAILED
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the related group.
|
|
*
|
|
* @param array $value
|
|
*/
|
|
protected function setEntity(array $value): void {
|
|
$this->group = $value;
|
|
}
|
|
|
|
/**
|
|
* Check if the group is an AD mailing list.
|
|
* @return bool
|
|
*/
|
|
public function isADGroup(): bool {
|
|
return !empty($this->group[static::CUSTOM_GROUP_NAME . '.Active_Directory_SID']);
|
|
}
|
|
|
|
/**
|
|
* Get a list of recipients indexed by email address.
|
|
*
|
|
* @return array List of recipients (MailListRecipient)
|
|
* @throws \Civi\Mailinglistsync\Exceptions\MailinglistException
|
|
*/
|
|
public function getRecipients(): array {
|
|
try {
|
|
$recipientData = Contact::get()
|
|
->addSelect('id', 'first_name', 'last_name', 'email.email', 'Active_Directory.SID')
|
|
->addJoin('Email AS email', 'LEFT', ['id', '=', 'email.contact_id'])
|
|
->addJoin('GroupContact AS group_contact', 'INNER',
|
|
['id', '=', 'group_contact.contact_id'],
|
|
['group_contact.group_id', '=', $this->group['id']],
|
|
['group_contact.status', '=', '"Added"'],
|
|
)
|
|
->addGroupBy('id')
|
|
->execute()
|
|
->getArrayCopy();
|
|
}
|
|
catch (\Exception $e) {
|
|
throw new MailinglistException(
|
|
"Could not get recipients for group with id '{$this->group['id']}'\n$e",
|
|
MailinglistException::ERROR_CODE_GET_RECIPIENTS_FAILED
|
|
);
|
|
}
|
|
|
|
$recipients = [];
|
|
foreach ($recipientData as $recipient) {
|
|
try {
|
|
$recipients[$recipient['email.email']] = new MailingListRecipient(
|
|
sid: $recipient['Active_Directory.SID'],
|
|
contact_id: $recipient['id'],
|
|
first_name: $recipient['first_name'],
|
|
last_name: $recipient['last_name'],
|
|
email: $recipient['email.email'],
|
|
);
|
|
} catch (\Exception $e) {
|
|
throw new MailinglistException(
|
|
"Could not create recipient object for contact with id '{$recipient['id']}': {$e->getMessage()}",
|
|
MailinglistException::ERROR_CODE_GET_RECIPIENTS_FAILED
|
|
);
|
|
}
|
|
}
|
|
|
|
return $recipients;
|
|
}
|
|
|
|
/**
|
|
* Update the title of the group.
|
|
*
|
|
* @param string $title
|
|
*
|
|
* @return void
|
|
* @throws \Civi\Mailinglistsync\Exceptions\MailinglistException
|
|
*/
|
|
public function updateGroupTitle(string $title): void {
|
|
$this->update(['title' => $title]);
|
|
}
|
|
|
|
/**
|
|
* Update the description of the group.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getGroupDescription(): string {
|
|
return $this->group['description'] ?? '';
|
|
}
|
|
|
|
/**
|
|
* Update the description of the group.
|
|
*
|
|
* @param string $description
|
|
*
|
|
* @return void
|
|
*/
|
|
public function updateGroupDescription(string $description): void {
|
|
$this->update(['description' => $description]);
|
|
}
|
|
|
|
/**
|
|
* 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, int $contactEmailId = NULL): void {
|
|
try {
|
|
$query = \Civi\Api4\GroupContact::create()
|
|
->addValue('contact_id', $contactId)
|
|
->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') {
|
|
$this->reAddContactToGroup($contactId);
|
|
}
|
|
else {
|
|
throw new MailinglistException(
|
|
"Could not add contact with id '$contactId' to group with id '{$this->group['id']}': $e",
|
|
MailinglistException::ERROR_CODE_ADD_CONTACT_TO_GROUP_FAILED
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove a contact from this mailing lists related group.
|
|
*
|
|
* @param int $contactId
|
|
*
|
|
* @return void
|
|
* @throws \Civi\Mailinglistsync\Exceptions\MailinglistException
|
|
*/
|
|
protected function removeContactFromGroup(int $contactId): void {
|
|
try {
|
|
\Civi\Api4\GroupContact::update()
|
|
->addWhere('contact_id', '=', $contactId)
|
|
->addWhere('group_id', '=', $this->group['id'])
|
|
->addValue('status', 'Removed')
|
|
->execute();
|
|
}
|
|
catch (\Exception $e) {
|
|
throw new MailinglistException(
|
|
"Could not remove contact with id '$contactId' from group with id '{$this->group['id']}'\n$e",
|
|
MailinglistException::ERROR_CODE_REMOVE_CONTACT_FROM_GROUP_FAILED
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If a group_contact entry already exists, but is marked as removed,
|
|
* re-add the contact to the group.
|
|
*
|
|
* @param int $contactId
|
|
*
|
|
* @return void
|
|
* @throws \Civi\Mailinglistsync\Exceptions\MailinglistException
|
|
*/
|
|
private function reAddContactToGroup(int $contactId): void {
|
|
try {
|
|
\Civi\Api4\GroupContact::update()
|
|
->addWhere('contact_id', '=', $contactId)
|
|
->addWhere('group_id', '=', $this->group['id'])
|
|
->addValue('status', 'Added')
|
|
->execute();
|
|
}
|
|
catch (\Exception $e) {
|
|
throw new MailinglistException(
|
|
"Could not re-add contact with id '$contactId' to group with id '{$this->group['id']}': $e",
|
|
MailinglistException::ERROR_CODE_ADD_CONTACT_TO_GROUP_FAILED
|
|
);
|
|
}
|
|
}
|
|
|
|
}
|