Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
36 / 36
38.89% covered (danger)
38.89%
14 / 36
100.00% covered (success)
100.00%
10 / 10
CRAP
100.00% covered (success)
100.00%
1 / 1
AddsBeforeAfter
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
36 / 36
38.89% covered (danger)
38.89%
14 / 36
100.00% covered (success)
100.00%
10 / 10
111.29
100.00% covered (success)
100.00%
1 / 1
 before
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 beforeHandlers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mergeBeforeHandlers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setBeforeHandlers
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 after
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 afterHandlers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mergeAfterHandlers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setAfterHandlers
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 doMergeBeforeHandlers
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
14 / 14
21.43% covered (danger)
21.43%
3 / 14
100.00% covered (success)
100.00%
1 / 1
23.46
 doMergeAfterHandlers
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
14 / 14
21.43% covered (danger)
21.43%
3 / 14
100.00% covered (success)
100.00%
1 / 1
23.46
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Router;
6
7trait AddsBeforeAfter
8{
9    /** @var list<Before> */
10    protected array $beforeHandlers = [];
11
12    /** @var list<After> */
13    protected array $afterHandlers = [];
14
15    /** @psalm-api */
16    public function before(Before $beforeHandler): static
17    {
18        $this->beforeHandlers = $this->mergeBeforeHandlers([$beforeHandler]);
19
20        return $this;
21    }
22
23    /**
24     * @internal
25     * @return list<Before>
26     */
27    public function beforeHandlers(): array
28    {
29        return $this->beforeHandlers;
30    }
31
32    /**
33     * @internal
34     * @param list<Before> $beforeHandlers
35     * @return list<Before>
36     */
37    public function mergeBeforeHandlers(array $beforeHandlers): array
38    {
39        return $this->doMergeBeforeHandlers($this->beforeHandlers, $beforeHandlers);
40    }
41
42    /**
43     * @internal
44     * @param list<Before> $beforeHandlers
45     */
46    public function setBeforeHandlers(array $beforeHandlers): static
47    {
48        $this->beforeHandlers = $beforeHandlers;
49
50        return $this;
51    }
52
53    /** @psalm-api */
54    public function after(After $afterHandler): static
55    {
56        $this->afterHandlers = $this->mergeAfterHandlers([$afterHandler]);
57
58        return $this;
59    }
60
61    /**
62     * @internal
63     * @return list<After>
64     */
65    public function afterHandlers(): array
66    {
67        return $this->afterHandlers;
68    }
69
70    /**
71     * @internal
72     * @param list<After> $afterHandlers
73     * @return list<After>
74     */
75    public function mergeAfterHandlers(array $afterHandlers): array
76    {
77        return $this->doMergeAfterHandlers($this->afterHandlers, $afterHandlers);
78    }
79
80    /**
81     * @internal
82     * @param list<After> $afterHandlers
83     */
84    public function setAfterHandlers(array $afterHandlers): static
85    {
86        $this->afterHandlers = $afterHandlers;
87
88        return $this;
89    }
90
91    /**
92     * @param list<Before> $handlers
93     * @param list<Before> $newHandlers
94     * @return list<Before>
95     */
96    protected function doMergeBeforeHandlers(array $handlers, array $newHandlers): array
97    {
98        foreach ($newHandlers as $handler) {
99            $replaced = false;
100            $result = [];
101
102            foreach ($handlers as $h) {
103                if (!$replaced && $h->replace($handler)) {
104                    $replaced = true;
105                    $result[] = $handler;
106                } else {
107                    $result[] = $h;
108                }
109            }
110
111            $handlers = $result;
112
113            if (!$replaced) {
114                $handlers[] = $handler;
115            }
116        }
117
118        return $handlers;
119    }
120
121    /**
122     * @param list<After> $handlers
123     * @param list<After> $newHandlers
124     * @return list<After>
125     */
126    protected function doMergeAfterHandlers(array $handlers, array $newHandlers): array
127    {
128        foreach ($newHandlers as $handler) {
129            $replaced = false;
130            $result = [];
131
132            foreach ($handlers as $h) {
133                if (!$replaced && $h->replace($handler)) {
134                    $replaced = true;
135                    $result[] = $handler;
136                } else {
137                    $result[] = $h;
138                }
139            }
140
141            $handlers = $result;
142
143            if (!$replaced) {
144                $handlers[] = $handler;
145            }
146        }
147
148        return $handlers;
149    }
150}