Passed
Push — master ( 035a69...ef3bdc )
by Kirill
03:22
created

PipelineTrait::makePipeline()   A

Complexity

Conditions 6
Paths 9

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 12
c 1
b 0
f 0
dl 0
loc 23
rs 9.2222
cc 6
nc 9
nop 0
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Router\Traits;
13
14
use Psr\Container\ContainerExceptionInterface;
15
use Psr\Http\Server\MiddlewareInterface;
16
use Spiral\Http\Pipeline;
17
use Spiral\Router\Exception\RouteException;
18
use Spiral\Router\RouteInterface;
19
20
trait PipelineTrait
21
{
22
    use ContainerTrait;
23
24
    /** @var Pipeline */
25
    protected $pipeline;
26
27
    /** @var MiddlewareInterface|string[] */
28
    protected $middleware = [];
29
30
    /**
31
     * Associated middleware with route. New instance of route will be returned.
32
     *
33
     * Example:
34
     * $route->withMiddleware(new CacheMiddleware(100));
35
     * $route->withMiddleware(ProxyMiddleware::class);
36
     * $route->withMiddleware(ProxyMiddleware::class, OtherMiddleware::class);
37
     * $route->withMiddleware([ProxyMiddleware::class, OtherMiddleware::class]);
38
     *
39
     * @param MiddlewareInterface|string|array ...$middleware
40
     * @return RouteInterface|$this
41
     *
42
     * @throws RouteException
43
     */
44
    public function withMiddleware(...$middleware): RouteInterface
45
    {
46
        $route = clone $this;
47
48
        // array fallback
49
        if (count($middleware) === 1 && is_array($middleware[0])) {
50
            $middleware = $middleware[0];
51
        }
52
53
        foreach ($middleware as $item) {
54
            if (!is_string($item) && !$item instanceof MiddlewareInterface) {
55
                if (is_object($item)) {
56
                    $name = get_class($item);
57
                } else {
58
                    $name = gettype($item);
59
                }
60
61
                throw new RouteException("Invalid middleware `{$name}`");
62
            }
63
64
            $route->middleware[] = $item;
65
        }
66
67
        if ($route->pipeline !== null) {
68
            $route->pipeline = $route->makePipeline();
69
        }
70
71
        return $route;
72
    }
73
74
    /**
75
     * Get associated route pipeline.
76
     *
77
     * @return Pipeline
78
     *
79
     * @throws RouteException
80
     */
81
    protected function makePipeline(): Pipeline
82
    {
83
        // pre-aggregated
84
        if (count($this->middleware) === 1 && $this->middleware[0] instanceof Pipeline) {
85
            return $this->middleware[0];
86
        }
87
88
        try {
89
            $pipeline = $this->container->get(Pipeline::class);
90
91
            foreach ($this->middleware as $middleware) {
92
                if ($middleware instanceof MiddlewareInterface) {
93
                    $pipeline->pushMiddleware($middleware);
94
                } else {
95
                    // dynamically resolved
96
                    $pipeline->pushMiddleware($this->container->get($middleware));
97
                }
98
            }
99
        } catch (ContainerExceptionInterface $e) {
100
            throw new RouteException($e->getMessage(), $e->getCode(), $e);
0 ignored issues
show
Bug introduced by
The method getCode() does not exist on Psr\Container\ContainerExceptionInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Psr\Container\NotFoundExceptionInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

100
            throw new RouteException($e->getMessage(), $e->/** @scrutinizer ignore-call */ getCode(), $e);
Loading history...
Bug introduced by
The method getMessage() does not exist on Psr\Container\ContainerExceptionInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Psr\Container\NotFoundExceptionInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

100
            throw new RouteException($e->/** @scrutinizer ignore-call */ getMessage(), $e->getCode(), $e);
Loading history...
101
        }
102
103
        return $pipeline;
104
    }
105
}
106