Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
parameters:
ignoreErrors:
-
message: '#^Method Webware\\CommandBus\\Event\\ConfigProvider\:\:__invoke\(\) should return array\{dependencies\: array\{aliases\: array\<class\-string, class\-string\>, delegators\: array\<class\-string, list\<class\-string\>\>, factories\: array\<class\-string, class\-string\>\}, Webware\\CommandBus\\CommandBusInterface\: non\-empty\-array\<array\<array\{middleware\: class\-string, priority\?\: int\}\>\>\} but returns array\{dependencies\: array, Webware\\CommandBus\\CommandBusInterface\: array\{middleware_pipeline\: array\{list\<array\{middleware\: class\-string, priority\?\: int\}\>\}\}\}\.$#'
identifier: return.type
count: 1
path: src/ConfigProvider.php

-
message: '#^Method Webware\\CommandBus\\Event\\ConfigProvider\:\:getDependencies\(\) return type has no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: src/ConfigProvider.php

-
message: '#^Method Webware\\CommandBus\\Event\\ConfigProvider\:\:getPipeline\(\) should return array\{list\<array\{middleware\: class\-string, priority\?\: int\}\>\} but returns array\{array\{middleware\: ''Webware\\\\CommandBus\\\\Event\\\\Middleware\\\\PreHandleMiddleware'', priority\: 100\}, array\{middleware\: ''Webware\\\\CommandBus\\\\Event\\\\Middleware\\\\PostHandleMiddleware'', priority\: \-100\}\}\.$#'
identifier: return.type
count: 1
path: src/ConfigProvider.php

-
message: '#^Method Webware\\CommandBus\\Event\\Container\\EventDispatcherAwareDelegator\:\:__invoke\(\) should return object but returns mixed\.$#'
identifier: return.type
count: 1
path: src/Container/EventDispatcherAwareDelegator.php

-
message: '#^Parameter \#1 \$id of method Psr\\Container\\ContainerInterface\:\:get\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Container/ListenerProviderAggregateFactory.php

-
message: '#^Parameter \#1 \$id of method Psr\\Container\\ContainerInterface\:\:has\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Container/ListenerProviderAggregateFactory.php

-
message: '#^Parameter \#2 \$listener of method Phly\\EventDispatcher\\ListenerProvider\\AttachableListenerProvider\:\:listen\(\) expects callable\(\)\: mixed, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Container/ListenerProviderAggregateFactory.php

-
message: '#^Parameter \#2 \$listener of method Phly\\EventDispatcher\\ListenerProvider\\PrioritizedListenerProvider\:\:listen\(\) expects callable\(\)\: mixed, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Container/ListenerProviderAggregateFactory.php

-
message: '#^Parameter \#3 \$priority of method Phly\\EventDispatcher\\ListenerProvider\\PrioritizedListenerProvider\:\:listen\(\) expects int, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Container/ListenerProviderAggregateFactory.php
2 changes: 2 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
includes:
- phpstan-baseline.neon
parameters:
level: 10
paths:
Expand Down
Empty file removed src/.gitkeep
Empty file.
27 changes: 24 additions & 3 deletions src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@

declare(strict_types=1);

/**
* This file is part of the Webware Commandbus Event package.
*
* Copyright (c) 2026 Joey (aka Tyrsson) Smith <jsmith@webinertia.net>
* and contributors.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webware\CommandBus\Event;

use Laminas\ServiceManager\Factory\InvokableFactory;
use Phly\EventDispatcher\EventDispatcher;
use Phly\EventDispatcher\ListenerProvider\ListenerProviderAggregate;
use Psr\EventDispatcher\EventDispatcherInterface;
Expand All @@ -14,11 +23,14 @@

final class ConfigProvider
{
public const CONFIG_KEY = 'listeners';
public const LISTENER_KEY = 'listeners';

public const LISTENER_PROVIDER_KEY = 'listener_providers';

/**
* @phpstan-return array{
* dependencies: array{
* aliases: array<class-string, class-string>,
* delegators: array<class-string, list<class-string>>,
* factories: array<class-string, class-string>
* },
Expand All @@ -33,10 +45,11 @@ final class ConfigProvider
public function __invoke(): array
{
return [
'dependencies' => $this->getDependencies(),
'dependencies' => $this->getDependencies(),
CommandBusInterface::class => [
BusProvider::MIDDLEWARE_PIPELINE_KEY => $this->getPipeline(),
],
// self::LISTENER_KEY => $this->getListeners(),
];
}

Expand All @@ -53,6 +66,9 @@ private function getDependencies(): array
];
}

/**
* @return array{list<array{middleware: class-string, priority?: int}>}
*/
private function getPipeline(): array
{
return [
Expand All @@ -66,4 +82,9 @@ private function getPipeline(): array
],
];
}

// private function getListeners(): array
// {
// return [];
// }
}
17 changes: 14 additions & 3 deletions src/Container/EventDispatcherAwareDelegator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

declare(strict_types=1);

/**
* This file is part of the Webware Commandbus Event package.
*
* Copyright (c) 2026 Joey (aka Tyrsson) Smith <jsmith@webinertia.net>
* and contributors.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webware\CommandBus\Event\Container;

use Psr\Container\ContainerInterface;
Expand All @@ -13,9 +23,9 @@
final class EventDispatcherAwareDelegator
{
public function __invoke(
ContainerInterface $container,
string $requestedName,
callable $callback
ContainerInterface $container,
string $requestedName,
callable $callback,
): object {
$serviceInstance = $callback();
if (! $serviceInstance instanceof EventDispatcherAwareInterface) {
Expand All @@ -24,6 +34,7 @@ public function __invoke(
$eventDispatcher = $container->get(EventDispatcherInterface::class);
assert($eventDispatcher instanceof EventDispatcherInterface);
$serviceInstance->setEventDispatcher($eventDispatcher);

return $serviceInstance;
}
}
42 changes: 0 additions & 42 deletions src/Container/EventDispatcherInterfaceFactory.php

This file was deleted.

76 changes: 60 additions & 16 deletions src/Container/ListenerProviderAggregateFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,90 @@

declare(strict_types=1);

/**
* This file is part of the Webware Commandbus Event package.
*
* Copyright (c) 2026 Joey (aka Tyrsson) Smith <jsmith@webinertia.net>
* and contributors.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webware\CommandBus\Event\Container;

use Phly\EventDispatcher\ListenerProvider\AttachableListenerProvider;
use Phly\EventDispatcher\ListenerProvider\ListenerProviderAggregate;
use Phly\EventDispatcher\ListenerProvider\PrioritizedListenerProvider;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\ListenerProviderInterface;
use Webware\CommandBus\Event\ListenerInterface;
use Webware\CommandBus\Event\ConfigProvider;

use function is_array;
use function is_callable;
use function is_string;

/** @internal */
/**
* @internal
*/
final class ListenerProviderAggregateFactory
{
public function __invoke(ContainerInterface $container): ListenerProviderAggregate
{
// todo: need some defense here
$listeners = $container->get('config')['listeners'] ?? [];
/** @var array{listeners?: array<class-string, array<int, array{listener: callable|class-string, priority?: int}>>, listener_providers?: array<class-string>} $config */
$config = $container->get('config');
$listeners = $config[ConfigProvider::LISTENER_KEY] ?? [];
$listenerProviders = $config[ConfigProvider::LISTENER_PROVIDER_KEY] ?? [];
$prioritizedProvider = $container->get(PrioritizedListenerProvider::class);
$attachableProvider = $container->get(AttachableListenerProvider::class);
$aggregate = new ListenerProviderAggregate();
foreach ($listeners as $listener) {
if (is_array($listener)) {
if (isset($listener['listener'], $listener['priority'])) {
$prioritizedProvider->listen($listener['event'], $listener['listener'], $listener['priority']);
} else {
$attachableProvider->listen($listener['event'], $listener['listener']);

/** @var string $eventType */
/** @var array<int, array{listener: callable|class-string, priority?: int}|callable|class-string> $spec */
foreach ($listeners as $eventType => $spec) {
foreach ($spec as $listener) {
if (is_string($listener)) {
if ($container->has($listener)) {
$attachableProvider->listen($eventType, $container->get($listener));
} elseif (is_callable($listener)) {
$attachableProvider->listen($eventType, $listener);
}

continue;
}
continue;
}

if (is_string($listener)) {
$listener = $container->has($listener) ? $container->get($listener) : null;
if ($listener instanceof ListenerProviderInterface) {
$aggregate->attach($listener);
if (is_array($listener)) {
$resolvedListener = null;
if ($container->has($listener['listener'])) {
$resolvedListener = $container->get($listener['listener']);
} elseif (is_callable($listener['listener'])) {
$resolvedListener = $listener['listener'];
} else {
continue;
}

if ($listener['priority']) {
$prioritizedProvider->listen($eventType, $resolvedListener, $listener['priority']);
} else {
$attachableProvider->listen($eventType, $resolvedListener);
}

continue;
}
}
}

/** @var string $provider */
foreach ($listenerProviders as $provider) {
$providerInstance = $container->has($provider) ? $container->get($provider) : null;
if ($providerInstance instanceof ListenerProviderInterface) {
$aggregate->attach($providerInstance);
}
}

$aggregate->attach($prioritizedProvider);
$aggregate->attach($attachableProvider);

return $aggregate;
}
}
10 changes: 10 additions & 0 deletions src/EventDispatcherAwareInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

declare(strict_types=1);

/**
* This file is part of the Webware Commandbus Event package.
*
* Copyright (c) 2026 Joey (aka Tyrsson) Smith <jsmith@webinertia.net>
* and contributors.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webware\CommandBus\Event;

use Psr\EventDispatcher\EventDispatcherInterface;
Expand Down
12 changes: 11 additions & 1 deletion src/EventDispatcherAwareTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

declare(strict_types=1);

/**
* This file is part of the Webware Commandbus Event package.
*
* Copyright (c) 2026 Joey (aka Tyrsson) Smith <jsmith@webinertia.net>
* and contributors.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webware\CommandBus\Event;

use Psr\EventDispatcher\EventDispatcherInterface;
Expand All @@ -11,7 +21,7 @@
*/
trait EventDispatcherAwareTrait
{
private readonly EventDispatcherInterface $eventDispatcher;
protected EventDispatcherInterface $eventDispatcher;

public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): void
{
Expand Down
Loading
Loading