headless_cms-1.0.3/modules/headless_cms_notify_nats/src/Plugin/HeadlessNotifyTransport/HeadlessNotifyNatsTransport.php
modules/headless_cms_notify_nats/src/Plugin/HeadlessNotifyTransport/HeadlessNotifyNatsTransport.php
<?php
declare(strict_types=1);
namespace Drupal\headless_cms_notify_nats\Plugin\HeadlessNotifyTransport;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\headless_cms_notify\Attribute\HeadlessNotifyTransport;
use Drupal\headless_cms_notify\NotifyMessage\HeadlessNotifyMessageInterface;
use Drupal\headless_cms_notify\Plugin\HeadlessNotifyTransport\HeadlessNotifyTransportBase;
use Drupal\headless_cms_notify\Plugin\HeadlessNotifyTransportPluginFormInterface;
use Drupal\headless_cms_notify_nats\Event\HeadlessNotifyNatsBeforeSendEvent;
use Drupal\nats\NatsClientManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* A transport that sends messages via NATS.
*/
#[HeadlessNotifyTransport(
id: 'nats',
label: new TranslatableMarkup('NATS'),
)]
class HeadlessNotifyNatsTransport extends HeadlessNotifyTransportBase implements HeadlessNotifyTransportPluginFormInterface {
public function __construct(
protected readonly NatsClientManagerInterface $natsClientManager,
protected readonly EventDispatcherInterface $eventDispatcher,
array $configuration,
$plugin_id,
$plugin_definition,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$container->get(NatsClientManagerInterface::class),
$container->get('event_dispatcher'),
$configuration,
$plugin_id,
$plugin_definition,
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'nats_client' => '',
'topic_prefix' => '',
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = [];
$options = [];
foreach ($this->natsClientManager->getAvailableClients() as $key) {
$options[$key] = $key;
}
$form['nats_client'] = [
'#type' => 'select',
'#title' => $this->t('NATS Client'),
'#description' => $this->t('The NATS client to use for sending messages.'),
'#default_value' => $this->configuration['nats_client'],
'#required' => TRUE,
'#options' => $options,
];
$form['topic_prefix'] = [
'#type' => 'textfield',
'#title' => $this->t('Topic Prefix'),
'#description' => $this->t('The topic prefix to use. Every message sent via NATS is prefixed with this topic. Must not have a trailing dot.'),
'#default_value' => $this->configuration['topic_prefix'],
'#required' => TRUE,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$topicPrefix = $form_state->getValue('topic_prefix');
// Make sure the topic prefix only contains letters, numbers, dashes
// and dots, but does not end with a dot.
if (!preg_match('/^[a-zA-Z0-9\_\-\.]+[a-zA-Z0-9]+$/', $topicPrefix)) {
$form_state->setErrorByName('topic_prefix', $this->t('The topic prefix must only contain letters, numbers, dashes and dots. See here: https://docs.nats.io/nats-concepts/subjects#characters-allowed-and-recommended-for-subject-names'));
}
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['nats_client'] = $form_state->getValue('nats_client');
$this->configuration['topic_prefix'] = $form_state->getValue('topic_prefix');
}
/**
* {@inheritdoc}
*/
public function send(HeadlessNotifyMessageInterface $message): void {
$client = $this->natsClientManager->get($this->configuration['nats_client']);
$topic = vsprintf('%s.%s', [
$this->configuration['topic_prefix'],
$message->getType(),
]);
// Allow modification of topic via event.
$event = new HeadlessNotifyNatsBeforeSendEvent($topic, $message);
$this->eventDispatcher->dispatch($event, HeadlessNotifyNatsBeforeSendEvent::EVENT_NAME);
$client->publish($event->topic, $message->toJson());
}
}
