984ee147450aa096065204adfbd1eb3ad882dd03
[GitHub/WoltLab/WCF.git] /
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Laminas\HttpHandlerRunner\Emitter;
6
7 use Laminas\HttpHandlerRunner\Exception;
8 use Psr\Http\Message\ResponseInterface;
9 use ReturnTypeWillChange;
10 use SplStack;
11
12 /**
13 * Provides an EmitterInterface implementation that acts as a stack of Emitters.
14 *
15 * The implementations emit() method iterates itself.
16 *
17 * When iterating the stack, the first emitter to return a boolean
18 * true value will short-circuit iteration.
19 *
20 * @template-extends SplStack<EmitterInterface>
21 */
22 class EmitterStack extends SplStack implements EmitterInterface
23 {
24 /**
25 * Emit a response
26 *
27 * Loops through the stack, calling emit() on each; any that return a
28 * boolean true value will short-circuit, skipping any remaining emitters
29 * in the stack.
30 *
31 * As such, return a boolean false value from an emitter to indicate it
32 * cannot emit the response, allowing the next emitter to try.
33 */
34 public function emit(ResponseInterface $response): bool
35 {
36 foreach ($this as $emitter) {
37 if (false !== $emitter->emit($response)) {
38 return true;
39 }
40 }
41
42 return false;
43 }
44
45 /**
46 * Set an emitter on the stack by index.
47 *
48 * @param int $index
49 * @param EmitterInterface $emitter
50 * @return void
51 * @throws Exception\InvalidEmitterException If not an EmitterInterface instance.
52 */
53 #[ReturnTypeWillChange]
54 public function offsetSet($index, $emitter)
55 {
56 /** @psalm-suppress RedundantConditionGivenDocblockType */
57 $this->validateEmitter($emitter);
58 parent::offsetSet($index, $emitter);
59 }
60
61 /**
62 * Push an emitter to the stack.
63 *
64 * @param EmitterInterface $emitter
65 * @return void
66 * @throws Exception\InvalidEmitterException If not an EmitterInterface instance.
67 */
68 #[ReturnTypeWillChange]
69 public function push($emitter)
70 {
71 /** @psalm-suppress RedundantConditionGivenDocblockType */
72 $this->validateEmitter($emitter);
73 parent::push($emitter);
74 }
75
76 /**
77 * Unshift an emitter to the stack.
78 *
79 * @param EmitterInterface $emitter
80 * @return void
81 * @throws Exception\InvalidEmitterException If not an EmitterInterface instance.
82 */
83 #[ReturnTypeWillChange]
84 public function unshift($emitter)
85 {
86 /** @psalm-suppress RedundantConditionGivenDocblockType */
87 $this->validateEmitter($emitter);
88 parent::unshift($emitter);
89 }
90
91 /**
92 * Validate that an emitter implements EmitterInterface.
93 *
94 * @throws Exception\InvalidEmitterException For non-emitter instances.
95 * @psalm-assert EmitterInterface $emitter
96 */
97 private function validateEmitter(mixed $emitter): void
98 {
99 if (! $emitter instanceof EmitterInterface) {
100 throw Exception\InvalidEmitterException::forEmitter($emitter);
101 }
102 }
103 }