Skip to content

Commit d89d071

Browse files
authored
Event apply (#5)
* event-apply
1 parent 1956c44 commit d89d071

16 files changed

+625
-109
lines changed

phpstan.neon

+8
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,11 @@ parameters:
22
level: 8
33
paths:
44
- src
5+
ignoreErrors:
6+
-
7+
message: '/Method Era269\\MessageProcessor\\AbstractMessageProcessor::getMethodName\(\) should return string but returns string\|false./'
8+
path: ./src/Traits/CanGetMethodNameByMessageTrait.php
9+
-
10+
message: '/Method Era269\\MessageProcessor\\AbstractMessageProcessor::getApplyEventMethodName\(\) should return string but returns string\|false./'
11+
path: ./src/Traits/CanGetMethodNameByEventTrait.php
12+

src/AbstractMessageProcessor.php

+6-15
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,13 @@
44

55
namespace Era269\MessageProcessor;
66

7-
use Era269\MessageProcessor\Message\NullMessage;
8-
use Era269\MessageProcessor\Traits\CanGetMethodNameByMessageTrait;
9-
use RuntimeException;
7+
use Era269\MessageProcessor\Traits\CacheAwareTrait;
8+
use Era269\MessageProcessor\Traits\CanApplyPrivateEventsTrait;
9+
use Era269\MessageProcessor\Traits\CanProcessMessage;
1010

1111
abstract class AbstractMessageProcessor implements MessageProcessorInterface
1212
{
13-
use CanGetMethodNameByMessageTrait;
14-
15-
/**
16-
* @throws RuntimeException
17-
*/
18-
final public function process(MessageInterface $message): MessageInterface
19-
{
20-
$methodName = $this->getMethodName($message);
21-
22-
return $this->$methodName($message)
23-
?? new NullMessage();
24-
}
13+
use CacheAwareTrait;
14+
use CanProcessMessage;
15+
use CanApplyPrivateEventsTrait;
2516
}

src/Message/EventInterface.php

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\Message;
6+
7+
use Era269\MessageProcessor\MessageInterface;
8+
9+
interface EventInterface extends MessageInterface
10+
{
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\MethodMap;
6+
7+
use Era269\MethodMap\MethodMapInterface;
8+
9+
abstract class AbstractMethodMapDecorator implements MethodMapInterface
10+
{
11+
/**
12+
* @var MethodMapInterface
13+
*/
14+
private $methodMap;
15+
16+
public function __construct(MethodMapInterface $methodMap)
17+
{
18+
$this->methodMap = $methodMap;
19+
}
20+
21+
/**
22+
* @inheritDoc
23+
*/
24+
public function getMethodNames($object): array
25+
{
26+
return $this->getDecorated(
27+
$this->methodMap->getMethodNames($object),
28+
$object
29+
);
30+
}
31+
32+
/**
33+
* @param string[] $methodNames
34+
* @param object $message
35+
*
36+
* @return string[]
37+
*/
38+
abstract protected function getDecorated(array $methodNames, $message): array;
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\MethodMap;
6+
7+
use Era269\MethodMap\MethodMapInterface;
8+
9+
final class ExcludeMethodMapDecorator extends AbstractMethodMapDecorator implements MethodMapInterface
10+
{
11+
/**
12+
* @var string[]
13+
*/
14+
private $exclude;
15+
16+
/**
17+
* @param string[] $exclude
18+
*/
19+
public function __construct(MethodMapInterface $methodMap, array $exclude)
20+
{
21+
parent::__construct($methodMap);
22+
$this->exclude = $exclude;
23+
}
24+
25+
/**
26+
* @inheritDoc
27+
*/
28+
protected function getDecorated(array $methodNames, $message): array
29+
{
30+
return array_diff(
31+
$methodNames,
32+
$this->exclude
33+
);
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\MethodMap;
6+
7+
use Era269\MethodMap\MethodMapInterface;
8+
use LogicException;
9+
10+
final class OneOrLessMethodMapDecorator extends AbstractMethodMapDecorator implements MethodMapInterface
11+
{
12+
/**
13+
* @inheritDoc
14+
*/
15+
protected function getDecorated(array $methodNames, $message): array
16+
{
17+
if (count($methodNames) > 1) {
18+
throw new LogicException(sprintf(
19+
'Controversial internal method call. More than one method [%s] can process "%s"',
20+
implode(',', $methodNames),
21+
get_class($message)
22+
));
23+
}
24+
return $methodNames;
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\MethodMap;
6+
7+
use Era269\MethodMap\MethodMapInterface;
8+
use LogicException;
9+
10+
final class OneOrMoreMethodMapDecorator extends AbstractMethodMapDecorator implements MethodMapInterface
11+
{
12+
/**
13+
* @inheritDoc
14+
*/
15+
protected function getDecorated(array $methodNames, $message): array
16+
{
17+
if (empty($methodNames)) {
18+
throw new LogicException(sprintf(
19+
'Incorrect internal method call: object doesn\'t know how to process the message "%s"',
20+
get_class($message)
21+
));
22+
}
23+
return $methodNames;
24+
}
25+
}

src/Traits/CacheAwareTrait.php

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\Traits;
6+
7+
use Cache\Adapter\PHPArray\ArrayCachePool;
8+
use Psr\SimpleCache\CacheInterface;
9+
10+
trait CacheAwareTrait
11+
{
12+
/**
13+
* @var CacheInterface
14+
*/
15+
private $cache;
16+
17+
public function setCache(CacheInterface $cache): void
18+
{
19+
$this->cache = $cache;
20+
}
21+
22+
private function getCache(): CacheInterface
23+
{
24+
if (!isset($this->cache)) {
25+
$this->cache = new ArrayCachePool();
26+
}
27+
return $this->cache;
28+
}
29+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\Traits;
6+
7+
use Era269\MessageProcessor\Message\EventInterface;
8+
9+
trait CanApplyPrivateEventsTrait
10+
{
11+
use CanGetMethodNameByEventTrait;
12+
13+
protected function apply(EventInterface ...$events): void
14+
{
15+
foreach ($events as $event) {
16+
$this->applyThat($event);
17+
}
18+
}
19+
20+
private function applyThat(EventInterface $event): void
21+
{
22+
$methodName = $this->getApplyEventMethodName($event);
23+
$this->{$methodName}($event);
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Era269\MessageProcessor\Traits;
6+
7+
use Era269\MessageProcessor\Message\EventInterface;
8+
use Era269\MessageProcessor\MethodMap\OneOrLessMethodMapDecorator;
9+
use Era269\MessageProcessor\MethodMap\OneOrMoreMethodMapDecorator;
10+
use Era269\MethodMap\ClassNameMethodMap;
11+
use Era269\MethodMap\MethodMapCacheDecorator;
12+
use Era269\MethodMap\MethodMapInterface;
13+
use Psr\SimpleCache\CacheInterface;
14+
use ReflectionMethod;
15+
16+
trait CanGetMethodNameByEventTrait
17+
{
18+
/**
19+
* @var MethodMapInterface
20+
*/
21+
private $applyEventMap;
22+
23+
/**
24+
* @param ClassNameMethodMap $applyEventMap
25+
*/
26+
public function setApplyEventMap(MethodMapInterface $applyEventMap): void
27+
{
28+
$this->applyEventMap = $this->getDecoratedByExactlyOneMethodMap($applyEventMap);
29+
}
30+
31+
private function getApplyEventMethodName(EventInterface $event): string
32+
{
33+
return current(
34+
$this->getApplyEventMap()->getMethodNames($event)
35+
);
36+
}
37+
38+
private function getApplyEventMap(): MethodMapInterface
39+
{
40+
if (!isset($this->applyEventMap)) {
41+
$this->applyEventMap =
42+
new MethodMapCacheDecorator(
43+
$this->getDecoratedByExactlyOneMethodMap(
44+
new ClassNameMethodMap(
45+
static::class,
46+
ReflectionMethod::IS_PROTECTED
47+
)
48+
),
49+
$this->getCache(),
50+
static::class
51+
);
52+
}
53+
54+
return $this->applyEventMap;
55+
}
56+
57+
private function getDecoratedByExactlyOneMethodMap(MethodMapInterface $methodMap): MethodMapInterface
58+
{
59+
return new OneOrMoreMethodMapDecorator(
60+
new OneOrLessMethodMapDecorator(
61+
$methodMap
62+
)
63+
);
64+
}
65+
66+
abstract protected function getCache(): CacheInterface;
67+
}

0 commit comments

Comments
 (0)