• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

elephox-dev / framework / 4877852653

pending completion
4877852653

push

github

Ricardo Boss
WIP

38 of 38 new or added lines in 6 files covered. (100.0%)

3863 of 5835 relevant lines covered (66.2%)

8.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/modules/Web/src/RequestPipelineBuilder.php
1
<?php
2
declare(strict_types=1);
3

4
namespace Elephox\Web;
5

6
use Elephox\Collection\ArrayList;
7
use Elephox\DI\Contract\Resolver;
8
use Elephox\Support\Contract\ExceptionHandler;
9
use Elephox\Web\Contract\PipelineEndpoint;
10
use Elephox\Web\Contract\WebMiddleware;
11
use InvalidArgumentException;
12
use LogicException;
13

14
class RequestPipelineBuilder
15
{
16
        /**
17
         * @var ArrayList<WebMiddleware|class-string<WebMiddleware>> $middlewares
18
         */
19
        private ArrayList $middlewares;
20

21
        /**
22
         * @param PipelineEndpoint|null $endpoint
23
         * @param class-string<PipelineEndpoint>|null $endpointClass
24
         */
25
        public function __construct(
26
                private ?PipelineEndpoint $endpoint,
27
                private ?string $endpointClass,
28
        ) {
29
                /** @var ArrayList<WebMiddleware|class-string<WebMiddleware>> */
30
                $this->middlewares = new ArrayList();
31
        }
32

33
        /**
34
         * @param class-string<WebMiddleware>|WebMiddleware $middleware
35
         */
36
        public function push(WebMiddleware|string $middleware): self
37
        {
38
                $this->middlewares->add($middleware);
39

40
                return $this;
41
        }
42

43
        /**
44
         * @param class-string<WebMiddleware>|null $className
45
         *
46
         * @return WebMiddleware|class-string<WebMiddleware>
47
         */
48
        public function pop(?string $className = null): WebMiddleware|string
49
        {
50
                $predicate = $className === null ? null : static fn (WebMiddleware|string $middleware): bool => $middleware === $className || $middleware instanceof $className;
51

52
                /** @psalm-suppress InvalidArgument */
53
                return $this->middlewares->pop($predicate);
54
        }
55

56
        public function endpoint(PipelineEndpoint|string $endpoint): self
57
        {
58
                if (is_string($endpoint)) {
59
                        $interfaces = class_implements($endpoint);
60
                        if ($interfaces === false || !in_array(PipelineEndpoint::class, $interfaces, true)) {
61
                                throw new InvalidArgumentException('Given class name must implement ' . PipelineEndpoint::class);
62
                        }
63

64
                        /** @var class-string<PipelineEndpoint> $endpoint */
65
                        $this->endpoint = null;
66
                        $this->endpointClass = $endpoint;
67
                } else {
68
                        $this->endpoint = $endpoint;
69
                        $this->endpointClass = null;
70
                }
71

72
                return $this;
73
        }
74

75
        public function exceptionHandler(WebMiddleware&ExceptionHandler $exceptionHandler): self
76
        {
77
                /** @var int|null $key */
78
                $key = $this->middlewares->firstKeyOrDefault(null, static fn (string|WebMiddleware $middleware): bool => $middleware instanceof ExceptionHandler);
79

80
                if ($key === null) {
81
                        $this->middlewares->unshift($exceptionHandler);
82
                } else {
83
                        $this->middlewares->put($key, $exceptionHandler);
84
                }
85

86
                return $this;
87
        }
88

89
        public function build(Resolver $resolver): RequestPipeline
90
        {
91
                if ($this->endpoint === null && $this->endpointClass !== null) {
92
                        $this->endpoint = $resolver->instantiate($this->endpointClass);
93
                } elseif ($this->endpoint === null) {
94
                        throw new LogicException('Either an endpoint or the class name for an endpoint needs to be set');
95
                }
96

97
                assert($this->endpoint instanceof PipelineEndpoint, 'Invalid endpoint type, expected class implementing ' . PipelineEndpoint::class);
98

99
                /** @var ArrayList<WebMiddleware> $concreteMiddlewares */
100
                $concreteMiddlewares = new ArrayList();
101

102
                foreach ($this->middlewares as $middleware) {
103
                        if (is_string($middleware)) {
104
                                $concreteMiddleware = $resolver->instantiate($middleware);
105
                                if (!($concreteMiddleware instanceof WebMiddleware)) {
106
                                        throw new InvalidArgumentException("Given middleware '$middleware' does not implement " . WebMiddleware::class);
107
                                }
108

109
                                $concreteMiddlewares->add($concreteMiddleware);
110
                        } else {
111
                                $concreteMiddlewares->add($middleware);
112
                        }
113
                }
114

115
                return new RequestPipeline($this->endpoint, $concreteMiddlewares);
116
        }
117
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc