182 lines
5.3 KiB
PHP
182 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace Drupal\materio_mailjet;
|
|
|
|
use Drupal\Core\Config\ConfigFactoryInterface;
|
|
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
|
|
use Drupal\mailjet\MailjetFactory;
|
|
use Mailjet\Resources;
|
|
|
|
/**
|
|
* Syncs simplenews subscription events to Mailjet contact lists.
|
|
*
|
|
* Replacement for the unmaintained simplenews_mailjet_subscriptions module.
|
|
* Simplenews remains the consent store (owned data, provider-agnostic);
|
|
* Mailjet is a replaceable sender. The list mapping lives in
|
|
* materio_mailjet.settings, so switching provider only means replacing
|
|
* this adapter.
|
|
*/
|
|
class MaterioMailjetSync {
|
|
|
|
/**
|
|
* Mailjet client.
|
|
*
|
|
* @var \Mailjet\Client
|
|
*/
|
|
protected $mailjetClient;
|
|
|
|
/**
|
|
* Config factory.
|
|
*
|
|
* @var \Drupal\Core\Config\ConfigFactoryInterface
|
|
*/
|
|
protected $configFactory;
|
|
|
|
/**
|
|
* Logger.
|
|
*
|
|
* @var \Drupal\Core\Logger\LoggerChannelInterface
|
|
*/
|
|
protected $logger;
|
|
|
|
/**
|
|
* Constructs the sync service.
|
|
*/
|
|
public function __construct(ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, MailjetFactory $mailjet_factory) {
|
|
$this->configFactory = $config_factory;
|
|
$this->logger = $logger_factory->get('materio_mailjet');
|
|
$this->mailjetClient = $mailjet_factory->create();
|
|
}
|
|
|
|
/**
|
|
* Returns the Mailjet list IDs mapped to a simplenews newsletter.
|
|
*
|
|
* @param string $newsletter_id
|
|
* The simplenews newsletter ID.
|
|
*
|
|
* @return array
|
|
* List of Mailjet list IDs (may be empty).
|
|
*/
|
|
public function getListIdsForNewsletter(string $newsletter_id): array {
|
|
$mapping = $this->configFactory->get('materio_mailjet.settings')->get('list_mapping') ?? [];
|
|
$list_ids = [];
|
|
foreach ($mapping as $list_id => $news_id) {
|
|
if ($news_id === $newsletter_id) {
|
|
$list_ids[] = (string) $list_id;
|
|
}
|
|
}
|
|
return $list_ids;
|
|
}
|
|
|
|
/**
|
|
* Returns the simplenews newsletter mapped to a Mailjet list ID.
|
|
*
|
|
* @param int $list_id
|
|
* The Mailjet list ID.
|
|
*
|
|
* @return string|null
|
|
* The newsletter ID, or NULL if unmapped.
|
|
*/
|
|
public function getNewsletterForListId(int $list_id): ?string {
|
|
$mapping = $this->configFactory->get('materio_mailjet.settings')->get('list_mapping') ?? [];
|
|
return $mapping[$list_id] ?? NULL;
|
|
}
|
|
|
|
/**
|
|
* Subscribes an email to every Mailjet list mapped to a newsletter.
|
|
*/
|
|
public function subscribeToNewsletter(string $newsletter_id, string $email): void {
|
|
if (empty($email)) {
|
|
return;
|
|
}
|
|
foreach ($this->getListIdsForNewsletter($newsletter_id) as $list_id) {
|
|
$this->subscribeToList($list_id, $email);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unsubscribes an email from every Mailjet list mapped to a newsletter.
|
|
*/
|
|
public function unsubscribeFromNewsletter(string $newsletter_id, string $email): void {
|
|
if (empty($email)) {
|
|
return;
|
|
}
|
|
foreach ($this->getListIdsForNewsletter($newsletter_id) as $list_id) {
|
|
$this->unsubscribeFromList($list_id, $email);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unsubscribes an email from every mapped Mailjet list.
|
|
*/
|
|
public function unsubscribeFromAllLists(string $email): void {
|
|
if (empty($email)) {
|
|
return;
|
|
}
|
|
$mapping = $this->configFactory->get('materio_mailjet.settings')->get('list_mapping') ?? [];
|
|
foreach (array_keys($mapping) as $list_id) {
|
|
$this->unsubscribeFromList((string) $list_id, $email);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a contact to a Mailjet list (creates the contact if needed).
|
|
*/
|
|
public function subscribeToList(string $list_id, string $email): void {
|
|
if (!$this->ensureContact($email)) {
|
|
$this->logger->warning('@email does not exist and cannot be created on Mailjet.', ['@email' => $email]);
|
|
return;
|
|
}
|
|
|
|
$response = $this->mailjetClient->post(Resources::$ContactslistManagecontact, [
|
|
'id' => $list_id,
|
|
'body' => ['Action' => 'addnoforce', 'Email' => $email],
|
|
]);
|
|
|
|
if ($response->success()) {
|
|
$this->logger->notice('The Mailjet user @email subscribed to the @list list.', ['@email' => $email, '@list' => $list_id]);
|
|
}
|
|
else {
|
|
$this->logger->warning('Error while subscribing @email to the @list list.', ['@email' => $email, '@list' => $list_id]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes a contact from a Mailjet list.
|
|
*/
|
|
public function unsubscribeFromList(string $list_id, string $email): void {
|
|
$response = $this->mailjetClient->post(Resources::$ContactslistManagecontact, [
|
|
'id' => $list_id,
|
|
'body' => ['Action' => 'remove', 'Email' => $email],
|
|
]);
|
|
|
|
if ($response->success()) {
|
|
$this->logger->notice('The Mailjet user @email was removed from the @list list.', ['@email' => $email, '@list' => $list_id]);
|
|
}
|
|
else {
|
|
$this->logger->warning('Error while removing @email from the @list list.', ['@email' => $email, '@list' => $list_id]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ensures a Mailjet contact exists for an email.
|
|
*
|
|
* @return bool
|
|
* TRUE if the contact exists or was created.
|
|
*/
|
|
protected function ensureContact(string $email): bool {
|
|
$response = $this->mailjetClient->get(Resources::$Contact, ['id' => urlencode($email)]);
|
|
if ($response->success()) {
|
|
return TRUE;
|
|
}
|
|
|
|
$response = $this->mailjetClient->post(Resources::$Contact, ['body' => ['Email' => $email]]);
|
|
if ($response->success()) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
}
|