1 | <?php |
||
2 | |||
3 | namespace Smoren\EventRouter\Components; |
||
4 | |||
5 | use Smoren\EventRouter\Interfaces\EventConfigInterface; |
||
6 | use Smoren\EventRouter\Interfaces\EventInterface; |
||
7 | |||
8 | /** |
||
9 | * Map for storing event route rules |
||
10 | */ |
||
11 | class EventRouterMap |
||
12 | { |
||
13 | /** |
||
14 | * @var array<string, array<array{EventConfigInterface, callable}>> |
||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||
15 | * [origin => [[config, handler], ...], ...] |
||
16 | */ |
||
17 | protected array $originMap = []; |
||
18 | /** |
||
19 | * @var array<string, array<string, array<array{EventConfigInterface, callable}>>> |
||
0 ignored issues
–
show
|
|||
20 | * [origin => [name => [[config, handler], ...], ...], ...] |
||
21 | */ |
||
22 | protected array $originNameMap = []; |
||
23 | |||
24 | /** |
||
25 | * Adds new event router rule to map |
||
26 | * @param EventConfigInterface $config |
||
27 | * @param callable $handler |
||
28 | * @return void |
||
29 | */ |
||
30 | 11 | public function add(EventConfigInterface $config, callable $handler): void |
|
31 | { |
||
32 | 11 | [$origin, $name] = [$config->getOrigin(), $config->getName()]; |
|
33 | |||
34 | 11 | if($name === null) { |
|
35 | 11 | if(!isset($this->originMap[$origin])) { |
|
36 | 11 | $this->originNameMap[$origin] = []; |
|
37 | } |
||
38 | 11 | $this->originMap[$origin][] = [$config, $handler]; |
|
39 | } else { |
||
40 | 5 | if(!isset($this->originNameMap[$origin])) { |
|
41 | 1 | $this->originNameMap[$origin] = []; |
|
42 | } |
||
43 | 5 | if(!isset($this->originNameMap[$origin][$name])) { |
|
44 | 5 | $this->originNameMap[$origin][$name] = []; |
|
45 | } |
||
46 | 5 | $this->originNameMap[$origin][$name][] = [$config, $handler]; |
|
47 | } |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * Returns suitable handlers from map for event |
||
52 | * @param EventInterface $event |
||
53 | * @return callable[] |
||
54 | */ |
||
55 | 11 | public function get(EventInterface $event): array |
|
56 | { |
||
57 | 11 | $handlers = []; |
|
58 | |||
59 | /** |
||
60 | * @var EventConfigInterface $config |
||
61 | * @var callable $handler |
||
62 | */ |
||
63 | 11 | foreach($this->originMap[$event->getOrigin()] ?? [] as [$config, $handler]) { |
|
64 | 10 | if(!$this->hasRecipientsIntersection($config, $event)) { |
|
65 | 1 | continue; |
|
66 | } |
||
67 | 10 | if(!$this->applyExtraFilter($config, $event)) { |
|
68 | 1 | continue; |
|
69 | } |
||
70 | 10 | $handlers[] = $handler; |
|
71 | } |
||
72 | |||
73 | 11 | foreach($this->originNameMap[$event->getOrigin()][$event->getName()] ?? [] as [$config, $handler]) { |
|
74 | 5 | if(!$this->hasRecipientsIntersection($config, $event)) { |
|
75 | 1 | continue; |
|
76 | } |
||
77 | 5 | if(!$this->applyExtraFilter($config, $event)) { |
|
78 | 1 | continue; |
|
79 | } |
||
80 | 5 | $handlers[] = $handler; |
|
81 | } |
||
82 | |||
83 | 11 | return $handlers; |
|
84 | } |
||
85 | |||
86 | /** |
||
87 | * Returns true if config condition and event have intersection by recipients |
||
88 | * @param EventConfigInterface $config route config condition |
||
89 | * @param EventInterface $event event |
||
90 | * @return bool |
||
91 | */ |
||
92 | 11 | protected function hasRecipientsIntersection(EventConfigInterface $config, EventInterface $event): bool |
|
93 | { |
||
94 | 11 | $candidates = $config->getRecipients(); |
|
95 | |||
96 | 11 | if($candidates === null) { |
|
97 | 10 | return true; |
|
98 | } |
||
99 | |||
100 | 1 | $recipients = $event->getRecipients(); |
|
101 | |||
102 | 1 | return (bool)count(array_intersect($candidates, $recipients)); |
|
103 | } |
||
104 | |||
105 | /** |
||
106 | * Returns result of extra filter call for event |
||
107 | * @param EventConfigInterface $config route config condition |
||
108 | * @param EventInterface $event event |
||
109 | * @return bool |
||
110 | */ |
||
111 | 11 | protected function applyExtraFilter(EventConfigInterface $config, EventInterface $event): bool |
|
112 | { |
||
113 | 11 | return ($filter = $config->getExtraFilter()) === null || $filter($event); |
|
114 | } |
||
115 | } |
||
116 |