MiddlewareContainer::add()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the Borobudur-Kernel package.
4
 *
5
 * (c) Hexacodelabs <http://hexacodelabs.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Borobudur\Kernel\Middleware;
12
13
use Borobudur\DependencyInjection\ContainerAwareInterface;
14
use Borobudur\DependencyInjection\ContainerAwareTrait;
15
use Borobudur\Http\ParameterBag;
16
use Borobudur\Http\Request;
17
use Borobudur\Http\Response;
18
use Borobudur\Kernel\Exception\InvalidArgumentException;
19
use Borobudur\Routing\RequestContext;
20
use Closure;
21
22
/**
23
 * @author      Iqbal Maulana <[email protected]>
24
 * @created     8/15/15
25
 */
26
class MiddlewareContainer implements ContainerAwareInterface
27
{
28
    use ContainerAwareTrait;
29
30
    /**
31
     * @var MiddlewareInterface[]
32
     */
33
    private $middlewares = array();
34
35
    /**
36
     * @var MiddlewareInvoker[]
37
     */
38
    private $executes = array();
39
40
    /**
41
     * Add sets of middleware.
42
     *
43
     * @param array $middlewares
44
     */
45
    public function add(array $middlewares)
46
    {
47
        foreach ($middlewares as $middleware) {
48
            $this->set($middleware);
49
        }
50
    }
51
52
    /**
53
     * Register middleware.
54
     *
55
     * @param MiddlewareInterface $middleware
56
     */
57
    public function set(MiddlewareInterface $middleware)
58
    {
59
        $this->middlewares[$middleware->getName()] = $middleware;
60
    }
61
62
    /**
63
     * Check if middleware was registered.
64
     *
65
     * @param string $name
66
     *
67
     * @return bool
68
     */
69
    public function has($name)
70
    {
71
        return array_key_exists($name, $this->middlewares);
72
    }
73
74
    /**
75
     * Register sets of middleware to be invoke.
76
     *
77
     * @param array $middlewares
78
     * @param array $excepts
79
     * @param array $only
80
     */
81
    public function dispatches(array $middlewares, array $excepts = array(), array $only = array())
82
    {
83
        foreach ($middlewares as $middleware) {
84
            $this->dispatch($middleware)->except($excepts)->only($only);
85
        }
86
    }
87
88
    /**
89
     * Register middleware to be invoke.
90
     *
91
     * @param string $name
92
     * @param array  $params
93
     *
94
     * @return MiddlewareInvoker
95
     */
96
    public function dispatch($name, array $params = array())
97
    {
98
        if (isset($this->middlewares[$name])) {
99
            $middleware = $this->middlewares[$name];
100
            $middleware->setParameter(new ParameterBag((array) $params));
101
102
            if (method_exists($middleware, 'configure')) {
103
                $instance = $this->container->getDi()->create($middleware);
104
                $instance->callMethod('configure');
105
                $middleware = $instance->getOriginalInstance();
106
            }
107
108
            $this->executes[] = $invoker = new MiddlewareInvoker($middleware);
109
110
            return $invoker;
111
        }
112
113
        throw new InvalidArgumentException(sprintf('Middleware "%s" is not registered.', $name));
114
    }
115
116
    /**
117
     * Invoke middleware.
118
     *
119
     * @param Request        $request
120
     * @param RequestContext $context
121
     * @param Closure        $next
122
     * @param string|null    $action
123
     *
124
     * @return Response|mixed|null
125
     */
126
    public function invoke(Request $request, RequestContext $context, Closure $next, $action = null)
127
    {
128
        $executes = array_reverse($this->executes);
129
        foreach ($executes as $caller) {
130
            $next = function () use (&$request, &$context, $caller, $next, $action) {
131
                return $caller($request, $context, $next, $action);
132
            };
133
        }
134
135
        return call_user_func($next);
136
    }
137
}
138