Skip to content

Commit 3fb67c4

Browse files
authored
Merge pull request #58 from OpenClassrooms/add_event_factory
feat(event): refacto of eventInterceptor and EventFactory
2 parents e5cafd9 + de891e9 commit 3fb67c4

10 files changed

Lines changed: 140 additions & 61 deletions

File tree

phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ parameters:
1919
- '/Call to static method Webmozart\\Assert\\Assert::allIsInstanceOf\(\) with/'
2020
- '/Function compact\(\) should not be used/'
2121
- '/In method .+, caught "Throwable" must be rethrown. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception./'
22+
- '/Class OpenClassrooms\\ServiceProxy\\Model\\Event is neither abstract nor final./'
2223
exceptions:
2324
check:
2425
missingCheckedExceptionInThrows: true

src/FrameworkBridge/Symfony/Config/services.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\Messenger\Transport\Serialization\MessageSerializer;
66
use OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\Subscriber\ServiceProxySubscriber;
77
use OpenClassrooms\ServiceProxy\Handler\Impl\Cache\SymfonyCacheHandler;
8+
use OpenClassrooms\ServiceProxy\Interceptor\Impl\Event\ServiceProxyEventFactory;
89
use OpenClassrooms\ServiceProxy\Invoker\Impl\AggregateMethodInvoker;
910
use OpenClassrooms\ServiceProxy\ProxyFactory;
1011
use OpenClassrooms\ServiceProxy\ProxyFactoryConfiguration;
@@ -74,4 +75,8 @@
7475
service('annotation_reader')->nullOnInvalid(),
7576
])
7677
->tag('kernel.event_subscriber');
78+
79+
$services->set(ServiceProxyEventFactory::class)
80+
->autowire()
81+
->autoconfigure();
7782
};

src/Handler/Impl/Event/SymfonyEventDispatcherEventHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function dispatch(Event $event, ?string $queue = null): void
2626
{
2727
$this->eventDispatcher->dispatch(
2828
$event,
29-
$event->name . '.' . Transport::SYNC->value,
29+
$event->name,
3030
);
3131
}
3232

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenClassrooms\ServiceProxy\Interceptor\Config;
6+
7+
use OpenClassrooms\ServiceProxy\Model\Event;
8+
9+
final class EventInterceptorConfig
10+
{
11+
/**
12+
* @param class-string<Event> $eventInstanceClassName
13+
*/
14+
public function __construct(
15+
public readonly string $eventInstanceClassName = Event::class,
16+
) {
17+
}
18+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenClassrooms\ServiceProxy\Interceptor\Contract\Event;
6+
7+
use OpenClassrooms\ServiceProxy\Model\Event;
8+
use OpenClassrooms\ServiceProxy\Model\Request\Instance;
9+
use OpenClassrooms\ServiceProxy\Model\Request\Moment;
10+
11+
interface EventFactory
12+
{
13+
/**
14+
* @template T of Event
15+
* @param class-string<T> $eventClassName
16+
* @return T
17+
*/
18+
public function createFromSenderInstance(
19+
Instance $instance,
20+
Moment $moment = Moment::SUFFIX,
21+
?string $name = null,
22+
string $eventClassName = Event::class
23+
): Event;
24+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenClassrooms\ServiceProxy\Interceptor\Impl\Event;
6+
7+
use OpenClassrooms\ServiceProxy\Interceptor\Contract\Event\EventFactory;
8+
use OpenClassrooms\ServiceProxy\Model\Event;
9+
use OpenClassrooms\ServiceProxy\Model\Request\Instance;
10+
use OpenClassrooms\ServiceProxy\Model\Request\Moment;
11+
12+
final class ServiceProxyEventFactory implements EventFactory
13+
{
14+
/**
15+
* @template T of Event
16+
* @param class-string<T> $eventClassName
17+
* @return T
18+
*/
19+
public function createFromSenderInstance(
20+
Instance $instance,
21+
Moment $moment = Moment::SUFFIX,
22+
?string $name = null,
23+
string $eventClassName = Event::class
24+
): Event {
25+
return new $eventClassName(
26+
$instance->getReflection()->getName(),
27+
$instance->getReflection()->getShortName(),
28+
$instance->getMethod()->getName(),
29+
$instance->getMethod()->getParameters(),
30+
$name,
31+
$instance->getMethod()->getReturnedValue(),
32+
$instance->getMethod()->getException(),
33+
$moment,
34+
);
35+
}
36+
}

src/Interceptor/Impl/EventInterceptor.php

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
use OpenClassrooms\ServiceProxy\Attribute\Event;
88
use OpenClassrooms\ServiceProxy\Handler\Contract\EventHandler;
9+
use OpenClassrooms\ServiceProxy\Interceptor\Config\EventInterceptorConfig;
910
use OpenClassrooms\ServiceProxy\Interceptor\Contract\AbstractInterceptor;
11+
use OpenClassrooms\ServiceProxy\Interceptor\Contract\Event\EventFactory;
1012
use OpenClassrooms\ServiceProxy\Interceptor\Contract\PrefixInterceptor;
1113
use OpenClassrooms\ServiceProxy\Interceptor\Contract\SuffixInterceptor;
1214
use OpenClassrooms\ServiceProxy\Model\Request\Instance;
@@ -15,6 +17,14 @@
1517

1618
final class EventInterceptor extends AbstractInterceptor implements SuffixInterceptor, PrefixInterceptor
1719
{
20+
public function __construct(
21+
private readonly EventFactory $eventFactory,
22+
private readonly EventInterceptorConfig $config,
23+
iterable $handlers = [],
24+
) {
25+
parent::__construct($handlers);
26+
}
27+
1828
public function getPrefixPriority(): int
1929
{
2030
return 20;
@@ -28,15 +38,15 @@ public function getSuffixPriority(): int
2838
public function prefix(Instance $instance): Response
2939
{
3040
$attributes = $instance->getMethod()
31-
->getAttributesInstances(Event::class)
32-
;
41+
->getAttributesInstances(Event::class);
3342

3443
foreach ($attributes as $attribute) {
3544
$handlers = $this->getHandlers(EventHandler::class, $attribute);
36-
$event = \OpenClassrooms\ServiceProxy\Model\Event::createFromSenderInstance(
45+
$event = $this->eventFactory->createFromSenderInstance(
3746
$instance,
3847
Moment::PREFIX,
3948
$attribute->name,
49+
$this->config->eventInstanceClassName,
4050
);
4151
foreach ($handlers as $handler) {
4252
if ($attribute->isPre()) {
@@ -51,27 +61,28 @@ public function prefix(Instance $instance): Response
5161
public function suffix(Instance $instance): Response
5262
{
5363
$attributes = $instance->getMethod()
54-
->getAttributes(Event::class)
55-
;
64+
->getAttributes(Event::class);
5665

5766
foreach ($attributes as $attribute) {
5867
$attribute = $attribute->newInstance();
5968
$handlers = $this->getHandlers(EventHandler::class, $attribute);
6069
foreach ($handlers as $handler) {
6170
if ($attribute->isPost() && !$instance->getMethod()->threwException()) {
62-
$event = \OpenClassrooms\ServiceProxy\Model\Event::createFromSenderInstance(
71+
$event = $this->eventFactory->createFromSenderInstance(
6372
$instance,
6473
Moment::SUFFIX,
6574
$attribute->name,
75+
$this->config->eventInstanceClassName,
6676
);
6777
$handler->dispatch($event, $attribute->queue);
6878
}
6979

7080
if ($attribute->isOnException() && $instance->getMethod()->threwException()) {
71-
$event = \OpenClassrooms\ServiceProxy\Model\Event::createFromSenderInstance(
81+
$event = $this->eventFactory->createFromSenderInstance(
7282
$instance,
7383
Moment::EXCEPTION,
7484
$attribute->name,
85+
$this->config->eventInstanceClassName,
7586
);
7687
$handler->dispatch($event, $attribute->queue);
7788
}
@@ -89,7 +100,6 @@ public function supportsSuffix(Instance $instance): bool
89100
public function supportsPrefix(Instance $instance): bool
90101
{
91102
return $instance->getMethod()
92-
->hasAttribute(Event::class)
93-
;
103+
->hasAttribute(Event::class);
94104
}
95105
}

src/Model/Event.php

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,56 +5,48 @@
55
namespace OpenClassrooms\ServiceProxy\Model;
66

77
use OpenClassrooms\ServiceProxy\Attribute\Event\Transport;
8-
use OpenClassrooms\ServiceProxy\Model\Request\Instance;
98
use OpenClassrooms\ServiceProxy\Model\Request\Moment;
109

11-
final class Event
10+
class Event
1211
{
12+
public string $name;
13+
1314
/**
14-
* @param mixed[] $parameters
15+
* @param class-string $class
16+
* @param array<string, mixed> $parameters
1517
*/
1618
public function __construct(
17-
public readonly string $name,
1819
public readonly string $class,
1920
public readonly string $classShortName,
2021
public readonly string $method,
2122
public readonly array $parameters,
23+
?string $name = null,
2224
public readonly mixed $response = null,
2325
public readonly mixed $exception = null,
2426
public readonly Moment $type = Moment::SUFFIX
2527
) {
28+
$this->name = self::getName(
29+
className: $class,
30+
moment: $type,
31+
transport: Transport::SYNC,
32+
method: $method,
33+
name: $name
34+
);
2635
}
2736

28-
public static function createFromSenderInstance(
29-
Instance $instance,
30-
Moment $moment = Moment::SUFFIX,
31-
?string $name = null
32-
): self {
33-
/** @var class-string $className */
34-
$className = $instance->getReflection()->getName();
37+
public function getUseCaseRequest(): mixed
38+
{
39+
return $this->parameters['useCaseRequest'] ?? ($this->parameters['request'] ?? null);
40+
}
3541

36-
return new self(
37-
self::getName(
38-
className: $className,
39-
moment: $moment,
40-
method: $instance->getMethod()
41-
->getName(),
42-
name: $name,
43-
),
44-
$instance->getReflection()
45-
->getName(),
46-
$instance->getReflection()
47-
->getShortName(),
48-
$instance->getMethod()
49-
->getName(),
50-
$instance->getMethod()
51-
->getParameters(),
52-
$instance->getMethod()
53-
->getReturnedValue(),
54-
$instance->getMethod()
55-
->getException(),
56-
$moment,
57-
);
42+
public function getUseCaseResponse(): mixed
43+
{
44+
return $this->response;
45+
}
46+
47+
public function getUseCaseException(): mixed
48+
{
49+
return $this->exception;
5850
}
5951

6052
/**
@@ -70,7 +62,6 @@ public static function getName(
7062
if ($name !== null) {
7163
return $name;
7264
}
73-
7465
$parts = explode('\\', $className);
7566
$classShortName = array_pop($parts);
7667

@@ -80,25 +71,10 @@ public static function getName(
8071

8172
$name = mb_strtolower((string) preg_replace('/(?<=\\w)(?=[A-Z])/', '_$1', $name));
8273

83-
if ($transport !== null) {
74+
if ($transport !== null && $transport !== Transport::SYNC) {
8475
return "{$moment->value}.{$name}.{$transport->value}";
8576
}
8677

8778
return "{$moment->value}.{$name}";
8879
}
89-
90-
public function getUseCaseRequest(): mixed
91-
{
92-
return $this->parameters['useCaseRequest'] ?? ($this->parameters['request'] ?? null);
93-
}
94-
95-
public function getUseCaseResponse(): mixed
96-
{
97-
return $this->response;
98-
}
99-
100-
public function getUseCaseException(): mixed
101-
{
102-
return $this->exception;
103-
}
10480
}

tests/Interceptor/EventInterceptorTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace OpenClassrooms\ServiceProxy\Tests\Interceptor;
66

7+
use OpenClassrooms\ServiceProxy\Interceptor\Config\EventInterceptorConfig;
8+
use OpenClassrooms\ServiceProxy\Interceptor\Impl\Event\ServiceProxyEventFactory;
79
use OpenClassrooms\ServiceProxy\Interceptor\Impl\EventInterceptor;
810
use OpenClassrooms\ServiceProxy\ProxyFactory;
911
use OpenClassrooms\ServiceProxy\Tests\Double\Mock\Event\EventHandlerMock;
@@ -28,6 +30,8 @@ protected function setUp(): void
2830
$this->proxyFactory = $this->getProxyFactory(
2931
[
3032
new EventInterceptor(
33+
new ServiceProxyEventFactory(),
34+
new EventInterceptorConfig(),
3135
[$this->handler],
3236
),
3337
]

tests/ProxyFactoryTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
namespace OpenClassrooms\ServiceProxy\Tests;
66

7+
use OpenClassrooms\ServiceProxy\Interceptor\Config\EventInterceptorConfig;
78
use OpenClassrooms\ServiceProxy\Interceptor\Contract\PrefixInterceptor;
89
use OpenClassrooms\ServiceProxy\Interceptor\Contract\SuffixInterceptor;
910
use OpenClassrooms\ServiceProxy\Interceptor\Impl\CacheInterceptor;
11+
use OpenClassrooms\ServiceProxy\Interceptor\Impl\Event\ServiceProxyEventFactory;
1012
use OpenClassrooms\ServiceProxy\Interceptor\Impl\EventInterceptor;
1113
use OpenClassrooms\ServiceProxy\Interceptor\Impl\InvalidateCacheInterceptor;
1214
use OpenClassrooms\ServiceProxy\Interceptor\Impl\LegacyCacheInterceptor;
@@ -37,7 +39,10 @@ protected function setUp(): void
3739
$classes = get_declared_classes();
3840

3941
foreach ($classes as $class) {
40-
if (is_subclass_of($class, PrefixInterceptor::class) || is_subclass_of($class, SuffixInterceptor::class)) {
42+
if ($class === EventInterceptor::class) {
43+
$interceptors[] = new $class(new ServiceProxyEventFactory(), new EventInterceptorConfig());
44+
} elseif (is_subclass_of($class, PrefixInterceptor::class)
45+
|| is_subclass_of($class, SuffixInterceptor::class)) {
4146
$interceptors[] = new $class();
4247
}
4348
}

0 commit comments

Comments
 (0)