Middleware::layer()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 9
cts 9
cp 1
rs 9.7666
c 0
b 0
f 0
cc 4
nc 8
nop 1
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Nymfonya\Component\Http;
6
7
use Closure;
8
use Nymfonya\Component\Container;
9
use Nymfonya\Component\Http\Interfaces\MiddlewareInterface;
10
11
/**
12
 * Nymfonya\Component\Http\Middleware
13
 *
14
 * is a copy/paste from onion team.
15
 *
16
 * @see https://github.com/esbenp/onion
17
 * @todo Thanks onion team, but composer install fails.
18
 */
19
class Middleware
20
{
21
22
    protected static $excMsg = ' is not a valid onion layer.';
23
    protected $layers;
24
25
    /**
26
     * instanciate
27
     *
28
     * @param array $layers
29
     */
30 7
    public function __construct(array $layers = [])
31
    {
32 7
        $this->layers = $layers;
33
    }
34
35
    /**
36
     * Add layer(s) or Middleware
37
     *
38
     * @param  mixed $layers
39
     * @return Middleware
40
     */
41 2
    public function layer($layers)
42
    {
43 2
        if ($layers instanceof Middleware) {
44 1
            $layers = $layers->toArray();
45
        }
46 2
        if ($layers instanceof MiddlewareInterface) {
47 1
            $layers = [$layers];
48
        }
49 2
        if (!is_array($layers)) {
50 1
            throw new \InvalidArgumentException(
51 1
                get_class($layers) . self::$excMsg
52
            );
53
        }
54 1
        return new static(array_merge($this->layers, $layers));
55
    }
56
57
    /**
58
     * Run middleware around core function and pass an
59
     * object through it
60
     *
61
     * @param  Container $container
62
     * @param  Closure $core
63
     * @return mixed
64
     */
65 1
    public function peel(Container $container, Closure $core)
66
    {
67 1
        $coreFunction = $this->createCoreFunction($core);
68 1
        $layers = array_reverse($this->layers);
69 1
        $completeMiddleware = array_reduce(
70 1
            $layers,
71 1
            [$this, 'createLayer'],
72
            $coreFunction
73
        );
74 1
        return $completeMiddleware($container);
75
    }
76
77
    /**
78
     * Get the layers of this onion,
79
     * can be used to merge with another onion
80
     *
81
     * @return array
82
     */
83 2
    public function toArray(): array
84
    {
85 2
        return $this->layers;
86
    }
87
88
    /**
89
     * The inner function of the onion.
90
     * this will be wrapped on layers
91
     *
92
     * @param  Closure $core the core function
93
     * @return Closure
94
     */
95 1
    protected function createCoreFunction(Closure $core): Closure
96
    {
97
        return function ($object) use ($core) {
98 1
            return $core($object);
99 1
        };
100
    }
101
102
    /**
103
     * Get an onion layer function.
104
     * we get the object from a previous layer and pass it inwards
105
     *
106
     * @param  Closure $nextLayer
107
     * @param  MiddlewareInterface $layer
108
     * @return Closure
109
     */
110 1
    protected function createLayer(Closure $nextLayer, MiddlewareInterface $layer): Closure
111
    {
112
        return function ($object) use ($nextLayer, $layer) {
113 1
            return $layer->peel($object, $nextLayer);
114 1
        };
115
    }
116
}
117