diff --git a/.woodpecker/code-style.yml b/.woodpecker/code-style.yml
new file mode 100644
index 0000000..bfd94b0
--- /dev/null
+++ b/.woodpecker/code-style.yml
@@ -0,0 +1,8 @@
+pipeline:
+ code-style:
+ image: composer
+ commands:
+ - composer global config repositories.repo-name vcs https://git.digital-competence.de/Packages/php-codesniffer
+ - composer global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
+ - composer global require digicomp/php-codesniffer:@dev
+ - composer global exec -- phpcs --runtime-set ignore_warnings_on_exit 1 --standard=DigiComp Classes/ Tests/
diff --git a/.woodpecker/functional-tests.yml b/.woodpecker/functional-tests.yml
new file mode 100644
index 0000000..c0a44a5
--- /dev/null
+++ b/.woodpecker/functional-tests.yml
@@ -0,0 +1,27 @@
+workspace:
+ base: /woodpecker
+ path: package
+
+matrix:
+ include:
+ - FLOW_VERSION: 8.2
+ PHP_VERSION: 8.1
+
+pipeline:
+ functional-tests:
+ image: "thecodingmachine/php:${PHP_VERSION}-v4-cli"
+ environment:
+ # Enable the PDO_SQLITE extension
+ - "PHP_EXTENSION_PDO_SQLITE=1"
+ - "FLOW_VERSION=${FLOW_VERSION}"
+ - "NEOS_BUILD_DIR=/woodpecker/Build-${FLOW_VERSION}"
+ commands:
+ - "sudo mkdir $NEOS_BUILD_DIR"
+ - "sudo chown -R docker:docker $NEOS_BUILD_DIR"
+ - "cd $NEOS_BUILD_DIR"
+ - "composer create-project --no-install neos/flow-base-distribution:^$FLOW_VERSION ."
+ - "composer config repositories.repo-name path /woodpecker/package"
+ - "composer config --no-plugins allow-plugins.neos/composer-plugin true"
+ - "composer remove --dev --no-update neos/behat || composer remove --no-update neos/behat"
+ - "composer require digicomp/flow-symfony-bridge-messenger:@dev"
+ - "bin/phpunit --configuration Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/DigiComp.FlowSymfonyBridge.Messenger/Tests/Functional"
diff --git a/Classes/Command/FailedCommandController.php b/Classes/Command/FailedCommandController.php
index 9b927b2..adb2337 100644
--- a/Classes/Command/FailedCommandController.php
+++ b/Classes/Command/FailedCommandController.php
@@ -14,16 +14,10 @@ class FailedCommandController extends CommandController
{
use RunSymfonyCommandTrait;
- /**
- * @Flow\Inject(name="DigiComp.FlowSymfonyBridge.Messenger:ReceiversContainer")
- * @var ContainerInterface
- */
- protected $receiverContainer;
+ #[Flow\Inject(name: 'DigiComp.FlowSymfonyBridge.Messenger:ReceiversContainer')]
+ protected ContainerInterface $receiverContainer;
- /**
- * @Flow\InjectConfiguration
- * @var array
- */
+ #[Flow\InjectConfiguration]
protected array $configuration;
/**
@@ -39,7 +33,7 @@ class FailedCommandController extends CommandController
*
* Optional arguments are -q (quiet) -v[v[v]] (verbosity) and --force (do not ask)
*/
- public function showCommand()
+ public function showCommand(): void
{
$command = new FailedMessagesShowCommand(
$this->configuration['failureTransport'],
@@ -59,7 +53,7 @@ class FailedCommandController extends CommandController
*
* Optional arguments are -q (quiet) -v[v[v]] (verbosity) and --force (do not ask)
*/
- public function removeCommand()
+ public function removeCommand(): void
{
$command = new FailedMessagesRemoveCommand(
$this->configuration['failureTransport'],
@@ -87,7 +81,7 @@ class FailedCommandController extends CommandController
*
* @noinspection PhpParamsInspection
*/
- public function retryCommand()
+ public function retryCommand(): void
{
$command = new FailedMessagesRetryCommand(
$this->configuration['failureTransport'],
diff --git a/Classes/Command/MessengerCommandController.php b/Classes/Command/MessengerCommandController.php
index de0930f..ade916b 100644
--- a/Classes/Command/MessengerCommandController.php
+++ b/Classes/Command/MessengerCommandController.php
@@ -17,47 +17,29 @@ class MessengerCommandController extends CommandController
{
use RunSymfonyCommandTrait;
- /**
- * @Flow\Inject(name="DigiComp.FlowSymfonyBridge.Messenger:RoutableMessageBus")
- * @var RoutableMessageBus
- */
- protected $routableBus;
+ #[Flow\Inject(name: 'DigiComp.FlowSymfonyBridge.Messenger:RoutableMessageBus')]
+ protected RoutableMessageBus $routableBus;
- /**
- * @Flow\Inject(name="DigiComp.FlowSymfonyBridge.Messenger:ReceiversContainer")
- * @var ContainerInterface
- */
- protected $receiverContainer;
+ #[Flow\Inject(name: 'DigiComp.FlowSymfonyBridge.Messenger:ReceiversContainer')]
+ protected ContainerInterface $receiverContainer;
- /**
- * @Flow\Inject(name="DigiComp.FlowSymfonyBridge.Messenger:EventDispatcher")
- * @var EventDispatcherInterface
- */
- protected $eventDispatcher;
+ #[Flow\Inject(name: 'DigiComp.FlowSymfonyBridge.Messenger:EventDispatcher')]
+ protected EventDispatcherInterface $eventDispatcher;
- /**
- * @Flow\Inject(lazy=false)
- * @var LoggerInterface
- */
+ #[Flow\Inject]
protected LoggerInterface $logger;
- /**
- * @Flow\InjectConfiguration
- * @var array
- */
+ #[Flow\InjectConfiguration]
protected array $configuration;
- /**
- * @Flow\Inject(name="DigiComp.FlowSymfonyBridge.Messenger:RestartSignalCachePool")
- * @var CacheItemPoolInterface
- */
- protected $restartSignalCachePool;
+ #[Flow\Inject(name: 'DigiComp.FlowSymfonyBridge.Messenger:RestartSignalCachePool')]
+ protected CacheItemPoolInterface $restartSignalCachePool;
/**
* Consumes messages and dispatches them to the message bus
*
* To receive from multiple transports, pass each name:
- * worker:consume receiver1 receiver2
+ * messenger:consume receiver1 receiver2
*
* Options are:
* --limit limits the number of messages received
@@ -71,7 +53,7 @@ class MessengerCommandController extends CommandController
*
* Optional arguments are -q (quiet) and -v[v[v]] (verbosity)
*/
- public function consumeCommand()
+ public function consumeCommand(): void
{
if ($this->receiverContainer instanceof DependencyProxy) {
$this->receiverContainer->_activateDependency();
@@ -92,7 +74,7 @@ class MessengerCommandController extends CommandController
/**
* List all available receivers
*/
- public function listReceiversCommand()
+ public function listReceiversCommand(): void
{
foreach (\array_keys($this->configuration['transports']) as $transportName) {
$this->outputLine('- ' . $transportName);
@@ -106,7 +88,7 @@ class MessengerCommandController extends CommandController
* and then exit. Worker commands are *not* automatically restarted: that
* should be handled by a process control system.
*/
- public function stopWorkersCommand()
+ public function stopWorkersCommand(): void
{
$cacheItem = $this->restartSignalCachePool->getItem(
StopWorkerOnRestartSignalListener::RESTART_REQUESTED_TIMESTAMP_KEY
diff --git a/Classes/Command/RunSymfonyCommandTrait.php b/Classes/Command/RunSymfonyCommandTrait.php
index b5e4779..a64bfa5 100644
--- a/Classes/Command/RunSymfonyCommandTrait.php
+++ b/Classes/Command/RunSymfonyCommandTrait.php
@@ -10,7 +10,7 @@ use Symfony\Component\Console\Output\OutputInterface;
trait RunSymfonyCommandTrait
{
- protected function run(Command $command)
+ protected function run(Command $command): void
{
$definition = $command->getDefinition();
$definition->setArguments(\array_merge(
@@ -29,7 +29,7 @@ trait RunSymfonyCommandTrait
$command->run($input, $this->output->getOutput());
}
- protected function configureIO($input, $output)
+ protected function configureIO($input, $output): void
{
switch ($shellVerbosity = (int)\getenv('SHELL_VERBOSITY')) {
case -1:
diff --git a/Classes/EventDispatcherFactory.php b/Classes/EventDispatcherFactory.php
index 99fccad..fae1fa7 100644
--- a/Classes/EventDispatcherFactory.php
+++ b/Classes/EventDispatcherFactory.php
@@ -11,19 +11,13 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
// TODO: Maybe an own package for EntityManager bridge?
class EventDispatcherFactory
{
- /**
- * @Flow\Inject
- * @var ObjectManagerInterface
- */
- protected $objectManager;
+ #[Flow\Inject(lazy: false)]
+ protected ObjectManagerInterface $objectManager;
- /**
- * @Flow\InjectConfiguration
- * @var array
- */
- protected $configuration;
+ #[Flow\InjectConfiguration]
+ protected array $configuration;
- public function create()
+ public function create(): EventDispatcher
{
$eventDispatcher = new EventDispatcher();
@@ -36,7 +30,7 @@ class EventDispatcherFactory
return $eventDispatcher;
}
- private function addLazySubscribers(EventDispatcherInterface $eventDispatcher, $subscriberId)
+ private function addLazySubscribers(EventDispatcherInterface $eventDispatcher, $subscriberId): void
{
$subscriberClass = $this->objectManager->getClassNameByObjectName($subscriberId);
if (! \is_a($subscriberClass, EventSubscriberInterface::class, true)) {
diff --git a/Classes/EventListener/StopWorkerOnRestartSignalListener.php b/Classes/EventListener/StopWorkerOnRestartSignalListener.php
index 9d878a4..444decc 100644
--- a/Classes/EventListener/StopWorkerOnRestartSignalListener.php
+++ b/Classes/EventListener/StopWorkerOnRestartSignalListener.php
@@ -11,27 +11,19 @@ use Symfony\Component\Messenger\Event\WorkerStartedEvent;
// This is a 1 to one copy of the original event listener, with a modified RESTART_REQUESTED_TIMESTAMP_KEY to match
// the restriction of the cache ids in flow.
-// Also the DI is simplified
+// Additionally, the DI is simplified
-/**
- * @Flow\Scope("singleton")
- */
+#[Flow\Scope('singleton')]
class StopWorkerOnRestartSignalListener implements EventSubscriberInterface
{
public const RESTART_REQUESTED_TIMESTAMP_KEY = 'workers_restart_requested_timestamp';
- /**
- * @Flow\Inject(name="DigiComp.FlowSymfonyBridge.Messenger:RestartSignalCachePool")
- * @var CacheItemPoolInterface
- */
- protected $cachePool;
+ #[Flow\Inject(name: 'DigiComp.FlowSymfonyBridge.Messenger:RestartSignalCachePool', lazy: false)]
+ protected CacheItemPoolInterface $cachePool;
- /**
- * @Flow\Inject
- * @var LoggerInterface
- */
- protected $logger;
- private $workerStartedAt;
+ #[Flow\Inject(lazy: false)]
+ protected LoggerInterface $logger;
+ private float $workerStartedAt;
public function onWorkerStarted(): void
{
@@ -42,13 +34,11 @@ class StopWorkerOnRestartSignalListener implements EventSubscriberInterface
{
if ($this->shouldRestart()) {
$event->getWorker()->stop();
- if (null !== $this->logger) {
- $this->logger->info('Worker stopped because a restart was requested.');
- }
+ $this->logger->info('Worker stopped because a restart was requested.');
}
}
- public static function getSubscribedEvents()
+ public static function getSubscribedEvents(): array
{
return [
WorkerStartedEvent::class => 'onWorkerStarted',
diff --git a/Classes/HandlersLocatorFactory.php b/Classes/HandlersLocatorFactory.php
index a060ab9..4956257 100644
--- a/Classes/HandlersLocatorFactory.php
+++ b/Classes/HandlersLocatorFactory.php
@@ -5,31 +5,23 @@ namespace DigiComp\FlowSymfonyBridge\Messenger;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
use Neos\Flow\Reflection\ReflectionService;
+use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Messenger\Handler\HandlerDescriptor;
use Symfony\Component\Messenger\Handler\HandlersLocator;
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
class HandlersLocatorFactory
{
- /**
- * @Flow\InjectConfiguration
- * @var array
- */
- protected $configuration;
+ #[Flow\InjectConfiguration]
+ protected array $configuration;
- /**
- * @Flow\Inject
- * @var ObjectManagerInterface
- */
- protected $objectManager;
+ #[Flow\Inject(lazy: false)]
+ protected ObjectManagerInterface $objectManager;
- /**
- * @Flow\Inject
- * @var ReflectionService
- */
- protected $reflectionService;
+ #[Flow\Inject(lazy: false)]
+ protected ReflectionService $reflectionService;
- public function create($busName = 'default')
+ public function create($busName = 'default'): HandlersLocator
{
$messageHandlerClasses = $this->reflectionService
->getAllImplementationClassNamesForInterface(MessageSubscriberInterface::class);
@@ -50,6 +42,30 @@ class HandlersLocatorFactory
);
}
}
+ $asHandlerClasses = $this->reflectionService
+ ->getClassNamesByAnnotation(AsMessageHandler::class);
+ foreach ($asHandlerClasses as $asHandlerClass) {
+ /** @var AsMessageHandler[] $annotations */
+ $annotations = $this->reflectionService->getClassAnnotations($asHandlerClass, AsMessageHandler::class);
+ foreach ($annotations as $annotation) {
+ $config['from_transport'] = $annotation->fromTransport;
+ $config['priority'] = $annotation->priority;
+ $method = $annotation->method ?? '__invoke';
+ $messageName = $annotation->handles;
+ if ($messageName === null) {
+ $arguments = $this->reflectionService->getMethodParameters($asHandlerClass, $method);
+ $messageName = $arguments[\array_key_first($arguments)]['class'];
+ }
+ if ($annotation->bus !== null && $annotation->bus !== $busName) {
+ continue;
+ }
+ $handler = $this->objectManager->get($asHandlerClass);
+ $handlerDescriptors[$messageName][] = new HandlerDescriptor(
+ $this->objectManager->get($asHandlerClass),
+ $config
+ );
+ }
+ }
// TODO: Maybe we can allow handlers to be added to bus or globally by configuration?
return new HandlersLocator($handlerDescriptors);
diff --git a/Classes/MessageBusContainer.php b/Classes/MessageBusContainer.php
index e461003..5991da2 100644
--- a/Classes/MessageBusContainer.php
+++ b/Classes/MessageBusContainer.php
@@ -7,25 +7,17 @@ use Neos\Flow\Annotations as Flow;
use Psr\Container\ContainerInterface;
use Symfony\Component\Messenger\MessageBus;
-/**
- * @Flow\Scope("singleton")
- */
+#[Flow\Scope('singleton')]
class MessageBusContainer implements ContainerInterface
{
- /**
- * @Flow\InjectConfiguration(path="buses")
- * @var array
- */
- protected $configuration;
+ #[Flow\InjectConfiguration(path: 'buses')]
+ protected array $configuration;
/**
* @var MessageBus[]
*/
protected array $buses = [];
- /**
- * @inheritDoc
- */
public function get(string $id)
{
if (! isset($this->buses[$id])) {
@@ -35,10 +27,7 @@ class MessageBusContainer implements ContainerInterface
return $this->buses[$id];
}
- /**
- * @inheritDoc
- */
- public function has(string $id)
+ public function has(string $id): bool
{
return isset($this->configuration[$id]);
}
diff --git a/Classes/ObjectManagement/ChainedContainer.php b/Classes/ObjectManagement/ChainedContainer.php
index 22cd004..ace8ee5 100644
--- a/Classes/ObjectManagement/ChainedContainer.php
+++ b/Classes/ObjectManagement/ChainedContainer.php
@@ -23,7 +23,7 @@ class ChainedContainer implements ContainerInterface
throw new \InvalidArgumentException('Service id is unknown: ' . $id);
}
- public function has(string $id)
+ public function has(string $id): bool
{
foreach ($this->childContainers as $childContainer) {
if ($childContainer->has($id)) {
diff --git a/Classes/ObjectManagement/RewindableGenerator.php b/Classes/ObjectManagement/RewindableGenerator.php
index e6fe50b..869d132 100644
--- a/Classes/ObjectManagement/RewindableGenerator.php
+++ b/Classes/ObjectManagement/RewindableGenerator.php
@@ -15,11 +15,8 @@ use Psr\Log\LoggerInterface;
*/
class RewindableGenerator implements \IteratorAggregate, \Countable
{
- /**
- * @Flow\Inject
- * @var ObjectManagerInterface
- */
- protected $objectManager;
+ #[Flow\Inject(lazy: false)]
+ protected ObjectManagerInterface $objectManager;
private array $serviceIds;
@@ -46,14 +43,14 @@ class RewindableGenerator implements \IteratorAggregate, \Countable
};
}
- public function getIterator()
+ public function getIterator(): \Traversable
{
$g = $this->generator;
return $g();
}
- public function count()
+ public function count(): int
{
return \count($this->serviceIds);
}
diff --git a/Classes/RetryStrategiesContainer.php b/Classes/RetryStrategiesContainer.php
index 6041c9f..6beead2 100644
--- a/Classes/RetryStrategiesContainer.php
+++ b/Classes/RetryStrategiesContainer.php
@@ -8,22 +8,14 @@ use Psr\Container\ContainerInterface;
use Symfony\Component\Messenger\Retry\MultiplierRetryStrategy;
use Symfony\Component\Messenger\Retry\RetryStrategyInterface;
-/**
- * @Flow\Scope("singleton")
- */
+#[Flow\Scope('singleton')]
class RetryStrategiesContainer implements ContainerInterface
{
- /**
- * @Flow\InjectConfiguration
- * @var array
- */
+ #[Flow\InjectConfiguration]
protected array $configuration;
- /**
- * @Flow\Inject
- * @var ObjectManagerInterface
- */
- protected $objectManager;
+ #[Flow\Inject]
+ protected ObjectManagerInterface $objectManager;
/**
* @var RetryStrategyInterface[]
@@ -54,7 +46,7 @@ class RetryStrategiesContainer implements ContainerInterface
return $this->retryStrategies[$id];
}
- public function has(string $id)
+ public function has(string $id): bool
{
return isset($this->configuration['transports'][$id]);
}
diff --git a/Classes/Transport/FailureTransportContainer.php b/Classes/Transport/FailureTransportContainer.php
new file mode 100644
index 0000000..3b86a3c
--- /dev/null
+++ b/Classes/Transport/FailureTransportContainer.php
@@ -0,0 +1,31 @@
+transports[$id];
+ }
+
+ public function has(string $id): bool
+ {
+ return isset($this->transports[$id]);
+ }
+
+ public function set(string $id, TransportInterface $transport): void
+ {
+ $this->transports[$id] = $transport;
+ }
+}
diff --git a/Classes/Transport/FlowDoctrineTransportFactory.php b/Classes/Transport/FlowDoctrineTransportFactory.php
index f9c4d9d..b23cb31 100644
--- a/Classes/Transport/FlowDoctrineTransportFactory.php
+++ b/Classes/Transport/FlowDoctrineTransportFactory.php
@@ -13,9 +13,7 @@ use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
use Symfony\Component\Messenger\Transport\TransportInterface;
-/**
- * @Flow\Scope("singleton")
- */
+#[Flow\Scope('singleton')]
class FlowDoctrineTransportFactory implements TransportFactoryInterface
{
private EntityManagerInterface $entityManager;
@@ -51,11 +49,8 @@ class FlowDoctrineTransportFactory implements TransportFactoryInterface
return new DoctrineTransport($connection, $serializer);
}
- /**
- * @inheritDoc
- */
public function supports(string $dsn, array $options): bool
{
- return 0 === \strpos($dsn, 'flow-doctrine://');
+ return \str_starts_with($dsn, 'flow-doctrine://');
}
}
diff --git a/Classes/Transport/NullTransport.php b/Classes/Transport/NullTransport.php
index 77973af..e84c4e2 100644
--- a/Classes/Transport/NullTransport.php
+++ b/Classes/Transport/NullTransport.php
@@ -7,33 +7,21 @@ use Symfony\Component\Messenger\Transport\TransportInterface;
class NullTransport implements TransportInterface
{
- /**
- * @inheritDoc
- */
public function get(): iterable
{
return new \EmptyIterator();
}
- /**
- * @inheritDoc
- */
public function ack(Envelope $envelope): void
{
// do nothing
}
- /**
- * @inheritDoc
- */
public function reject(Envelope $envelope): void
{
// do nothing
}
- /**
- * @inheritDoc
- */
public function send(Envelope $envelope): Envelope
{
return $envelope;
diff --git a/Classes/Transport/NullTransportFactory.php b/Classes/Transport/NullTransportFactory.php
index 4915998..7856cf5 100644
--- a/Classes/Transport/NullTransportFactory.php
+++ b/Classes/Transport/NullTransportFactory.php
@@ -8,19 +8,13 @@ use Symfony\Component\Messenger\Transport\TransportInterface;
class NullTransportFactory implements TransportFactoryInterface
{
- /**
- * @inheritDoc
- */
public function createTransport(string $dsn, array $options, SerializerInterface $serializer): TransportInterface
{
return new NullTransport();
}
- /**
- * @inheritDoc
- */
public function supports(string $dsn, array $options): bool
{
- return 0 === \strpos($dsn, 'null://');
+ return \str_starts_with($dsn, 'null://');
}
}
diff --git a/Classes/Transport/TransportsContainer.php b/Classes/Transport/TransportsContainer.php
index d96a752..7eb192f 100644
--- a/Classes/Transport/TransportsContainer.php
+++ b/Classes/Transport/TransportsContainer.php
@@ -8,28 +8,20 @@ use Psr\Container\ContainerInterface;
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
use Symfony\Component\Messenger\Transport\TransportInterface;
-/**
- * @Flow\Scope("singleton")
- */
+#[Flow\Scope('singleton')]
class TransportsContainer implements ContainerInterface
{
- /**
- * @Flow\InjectConfiguration
- * @var array
- */
+ #[Flow\InjectConfiguration]
protected array $configuration;
- /**
- * @Flow\Inject
- * @var ObjectManagerInterface
- */
- protected $objectManager;
+ #[Flow\Inject(lazy: false)]
+ protected ObjectManagerInterface $objectManager;
- /**
- * @Flow\Inject(name="DigiComp.FlowSymfonyBridge.Messenger:TransportFactory")
- * @var TransportFactoryInterface
- */
- protected $transportFactory;
+ #[Flow\Inject(name: 'DigiComp.FlowSymfonyBridge.Messenger:TransportFactory', lazy: false)]
+ protected TransportFactoryInterface $transportFactory;
+
+ #[Flow\Inject(lazy: false)]
+ protected FailureTransportContainer $failureTransports;
/**
* @var TransportInterface[]
@@ -65,11 +57,16 @@ class TransportsContainer implements ContainerInterface
$transportDefinition['options'],
$this->objectManager->get($transportDefinition['serializer'])
);
+ if (isset($transportDefinition['failureTransport'])) {
+ $this->failureTransports->set($id, $this->get($transportDefinition['failureTransport']));
+ } elseif (isset($this->configuration['failureTransport'])) {
+ $this->failureTransports->set($id, $this->get($this->configuration['failureTransport']));
+ }
}
return $this->transports[$id];
}
- public function has(string $id)
+ public function has(string $id): bool
{
return isset($this->configuration['transports'][$id]);
}
diff --git a/Configuration/Objects.yaml b/Configuration/Objects.yaml
index 380de1e..6e2d395 100644
--- a/Configuration/Objects.yaml
+++ b/Configuration/Objects.yaml
@@ -89,6 +89,13 @@ DigiComp.FlowSymfonyBridge.Messenger:ReceiversContainer:
object: 'DigiComp\FlowSymfonyBridge\Messenger\Transport\TransportsContainer'
# TODO: add own receivers here, which are no transports
+DigiComp.FlowSymfonyBridge.Messenger:FailureSenderContainer:
+ className: 'DigiComp\FlowSymfonyBridge\Messenger\ObjectManagement\ChainedContainer'
+ scope: 'singleton'
+ arguments:
+ 1:
+ object: 'DigiComp\FlowSymfonyBridge\Messenger\Transport\FailureTransportContainer'
+
DigiComp.FlowSymfonyBridge.Messenger:EventDispatcher:
className: 'Symfony\Component\EventDispatcher\EventDispatcher'
scope: 'singleton'
@@ -133,10 +140,6 @@ Symfony\Component\Messenger\EventListener\SendFailedMessageToFailureTransportLis
arguments:
1:
object:
- factoryObjectName: 'DigiComp.FlowSymfonyBridge.Messenger:SendersContainer'
- factoryMethodName: 'get'
- arguments:
- 1:
- setting: 'DigiComp.FlowSymfonyBridge.Messenger.failureTransport'
+ name: 'DigiComp.FlowSymfonyBridge.Messenger:FailureSenderContainer'
2:
object: 'Psr\Log\LoggerInterface'
diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml
index cf638d5..58df117 100644
--- a/Configuration/Settings.yaml
+++ b/Configuration/Settings.yaml
@@ -10,7 +10,6 @@ DigiComp:
Messenger:
defaultBusName: "default"
defaultSerializerName: "DigiComp.FlowSymfonyBridge.Messenger:DefaultSerializer"
- # TODO: use this
defaultRetryStrategyOptions:
maxRetries: 3
# milliseconds delay
@@ -19,8 +18,8 @@ DigiComp:
# e.g. 1 second delay, 2 seconds, 4 seconds
multiplier: 2
maxDelay: 0
- # override all of this with a service that
- # implements Symfony\Component\Messenger\Retry\RetryStrategyInterface
+ # override all of this with a service that implements
+ # Symfony\Component\Messenger\Retry\RetryStrategyInterface
service: null
eventDispatcher:
@@ -55,7 +54,4 @@ DigiComp:
dsn: "null://"
failureTransport: "discard"
- # TODO: Receivers and Senders? (As far as I can see not possible in Symfony)
- # receivers:[]
- # senders: []
routing: []
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..81be53a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,58 @@
+# DigiComp.FlowSymfonyBridge.Messenger
+
+
+
+This packages brings a DI configuration for the `symfony/messenger` component, so it can be used easily in `neos/flow` projects.
+
+To see how to use it, you probably want to have a look at the [documentation](https://symfony.com/doc/current/messenger.html) of `symfony/messenger`.
+
+
+## Getting started
+
+To get it integrated, you all need to do is to get message bus injected:
+
+```php
+ #[Flow\Inject]
+ protected MessageBusInterface $messageBus;
+```
+
+And later in your method:
+
+```php
+ $this->messageBus->dispatch(new CustomMessage())
+```
+
+You should configure a routing, to let the messenger know, over which transport your message should be handled:
+
+```yaml
+DigiComp:
+ FlowSymfonyBridge:
+ Messenger:
+ transports:
+ "custom-messages":
+ dsn: "flow-doctrine://default?table_name=test_messenger_messages"
+ routing:
+ Acme\Vendor\Messenger\CustomMessage:
+ - "custom-messages"
+```
+
+In this example we are using a doctrine transport (the speciality "flow-transport" is a transport which uses the already existing connection to doctrine instead of creating a new one - for the rest of the DSN-Format have a look in the documentation of `symfony/messenger`)
+
+A handler for your CustomMessage could look like this:
+
+```php
+use Symfony\Component\Messenger\Attribute\AsMessageHandler;
+
+#[AsMessageHandler]
+class CustomMessageHandler
+{
+ public function __invoke(CustomMessage $message)
+ {
+ //your code here
+ }
+}
+```
+
+It will be automatically found by Flow // the messenger and messages arriving at the bus will be handled by your handler.
+
+Probably you'll want to consume the messengers with long living processes or as a cronjob. The Flow command for that task is `messenger:consume` (more help available)
diff --git a/Tests/Functional/Fixtures/Message/TestMessageHandler.php b/Tests/Functional/Fixtures/Message/TestMessageHandler.php
index bddf7d0..efb5f38 100644
--- a/Tests/Functional/Fixtures/Message/TestMessageHandler.php
+++ b/Tests/Functional/Fixtures/Message/TestMessageHandler.php
@@ -2,15 +2,11 @@
namespace DigiComp\FlowSymfonyBridge\Messenger\Tests\Functional\Fixtures\Message;
-use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
+use Symfony\Component\Messenger\Attribute\AsMessageHandler;
-class TestMessageHandler implements MessageSubscriberInterface
+#[AsMessageHandler]
+class TestMessageHandler
{
- public static function getHandledMessages(): iterable
- {
- yield TestMessage::class => [];
- }
-
public function __invoke(TestMessage $message)
{
//do nothing for now
diff --git a/composer.json b/composer.json
index 31776bd..cd76787 100644
--- a/composer.json
+++ b/composer.json
@@ -1,12 +1,12 @@
{
"name": "digicomp/flow-symfony-bridge-messenger",
"type": "neos-package",
- "license": "MIT",
"description": "Flow dependency injection bridge to symfony/messenger",
"require": {
- "neos/flow": "^6.3",
- "symfony/doctrine-messenger": "^5.2.5",
- "symfony/event-dispatcher": "^4.2 | ^5.2"
+ "php": "^8.1",
+ "neos/flow": "^8.0",
+ "symfony/doctrine-messenger": "^6.2",
+ "symfony/event-dispatcher": "^4.2 | ^5.2 | ^6.2"
},
"autoload": {
"psr-4": {
@@ -20,10 +20,26 @@
},
"extra": {
"branch-alias": {
- "dev-master": "0.0.x-dev"
+ "dev-master": "0.1.x-dev"
},
"neos": {
"package-key": "DigiComp.FlowSymfonyBridge.Messenger"
}
- }
+ },
+ "authors": [
+ {
+ "name": "Ferdinand Kuhl",
+ "email": "f.kuhl@digital-competence.de",
+ "homepage": "https://www.digital-competence.de",
+ "role": "Developer"
+ }
+ ],
+ "license": "MIT",
+ "homepage": "https://github.com/digital-competence/DigiComp.FlowSymfonyBridge.Messenger",
+ "keywords": [
+ "Neos",
+ "Flow",
+ "symfony",
+ "messenger"
+ ]
}