headless_cms-1.0.3/modules/headless_cms_notify/src/ConsumerHeadlessNotifyManager.php
modules/headless_cms_notify/src/ConsumerHeadlessNotifyManager.php
<?php
declare(strict_types=1);
namespace Drupal\headless_cms_notify;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\consumers\Entity\ConsumerInterface;
use Drupal\consumers\Negotiator;
use Drupal\headless_cms_notify\Entity\HeadlessNotifyTransportInterface;
use Drupal\headless_cms_notify\NotifyMessage\HeadlessNotifyEntityOperationMessage;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
/**
* Manages headless notify fields for consumer entities.
*/
class ConsumerHeadlessNotifyManager {
public function __construct(
protected readonly EntityTypeManagerInterface $entityTypeManager,
#[Autowire(service: 'consumer.negotiator')]
protected readonly Negotiator $negotiator,
protected readonly ConfigFactoryInterface $configFactory,
protected readonly AccountProxyInterface $currentUser,
protected readonly HeadlessNotifyTransportPluginManager $transportPluginManager,
#[Autowire(service: 'cache.headless_cms_notify')]
protected readonly CacheBackendInterface $cacheBackend,
) {}
/**
* Get applicable consumers for a notification type.
*
* This method is performance critical and therefore caches the
* result.
*/
public function getApplicableConsumers(string $notificationType, ?string $entityTypeId = NULL): array {
$ctags = [];
$cid = 'applicable_consumers:' . $notificationType . ':' . (string) $entityTypeId;
// Check if we have a cached result.
if ($item = $this->cacheBackend->get($cid)) {
return $item->data;
}
$applicableConsumers = [];
$allConsumers = $this->entityTypeManager->getStorage('consumer')->loadMultiple();
foreach ($allConsumers as $consumer) {
// If notification type is not enabled for consumer, skip.
if (!$this->isEnabled($notificationType, $consumer)) {
continue;
}
// If notification type is entity operation and entity type is not
// selected, skip.
if ($notificationType === HeadlessNotifyEntityOperationMessage::getMessageTypeId() && $entityTypeId && !$this->canNotifyEntityType($entityTypeId, $consumer)) {
continue;
}
$applicableConsumers[] = $consumer;
// Merge cache tags.
array_push($ctags, ...$consumer->getCacheTags());
}
// Cache the result.
$this->cacheBackend->set($cid, $applicableConsumers, CacheBackendInterface::CACHE_PERMANENT, $ctags);
return $applicableConsumers;
}
/**
* Check if the consumer has notifications enabled.
*
* Additionally, if the consumer has no transport set, it will
* return FALSE.
*/
public function isEnabled(?string $notificationType = NULL, ?ConsumerInterface $consumer = NULL): bool {
$consumer = $consumer ?? $this->negotiator->negotiateFromRequest();
if (!$consumer) {
return FALSE;
}
$enabled = $consumer->get('headless_cms_notify_enabled')->getString() === '1';
$enabledWithTransport = $enabled && !!$this->getNotifyTransport($consumer);
if (!$enabledWithTransport) {
return FALSE;
}
if (!$notificationType) {
return $enabledWithTransport;
}
return $this->isNotificationEnabled($notificationType, $consumer);
}
/**
* Get the notify plugin for the consumer.
*
* Uses the negotiated consumer if none is given.
*/
public function getNotifyTransport(?ConsumerInterface $consumer = NULL): ?HeadlessNotifyTransportInterface {
$consumer = $consumer ?? $this->negotiator->negotiateFromRequest();
if (!$consumer) {
return NULL;
}
$transportId = $consumer->get('headless_cms_notify_transport')->getString();
if (!$transportId) {
return NULL;
}
return $this->entityTypeManager->getStorage('headless_notify_transport')->load($transportId);
}
/**
* Check if givben notification type is enabled for a consumer.
*
* Uses the negotiated consumer if none is given.
*/
public function isNotificationEnabled(string $notificationType, ?ConsumerInterface $consumer = NULL): bool {
$consumer = $consumer ?? $this->negotiator->negotiateFromRequest();
if (!$consumer) {
return FALSE;
}
$savedValues = array_map(fn($v) => $v['value'], $consumer->get('headless_cms_notify_notification_types')->getValue() ?? []);
return in_array($notificationType, $savedValues);
}
/**
* Get the entity types for which notifications should be sent.
*/
public function getEntityNotificationEntityTypes(?ConsumerInterface $consumer = NULL): array {
$consumer = $consumer ?? $this->negotiator->negotiateFromRequest();
if (!$consumer) {
return [];
}
return array_map(fn($v) => $v['value'], $consumer->get('headless_cms_notify_entity_types')->getValue() ?? []);
}
/**
* Checks whether the consumer should send notifications for the entity type.
*/
public function canNotifyEntityType(string $entityTypeId, ?ConsumerInterface $consumer = NULL): bool {
$consumer = $consumer ?? $this->negotiator->negotiateFromRequest();
if (!$consumer) {
return FALSE;
}
return in_array($entityTypeId, $this->getEntityNotificationEntityTypes($consumer));
}
}
