Files
materio-d9/web/modules/custom/materio_mailjet/src/MaterioMailjetSync.php
T

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;
}
}