Completed
Push — master ( 7dba56...6875ae )
by Oscar
10:21
created

Middleware::create()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4286
cc 3
eloc 8
nc 1
nop 1
1
<?php
2
3
namespace Psr7Middlewares;
4
5
use Psr\Http\Message\StreamInterface;
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ServerRequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use RuntimeException;
10
11
class Middleware
12
{
13
    const KEY = 'Psr7Middlewares\\Middleware';
14
15
    private static $streamFactory;
16
17
    /**
18
     * Set the stream factory used by some middlewares.
19
     *
20
     * @param callable $streamFactory
21
     */
22
    public static function setStreamFactory(callable $streamFactory)
23
    {
24
        self::$streamFactory = $streamFactory;
25
    }
26
27
    /**
28
     * Get the stream factory.
29
     *
30
     * @return StreamInterface
31
     */
32
    public static function createStream($file = 'php://temp', $mode = 'r+')
33
    {
34
        if (empty(self::$streamFactory)) {
35
            if (class_exists('Zend\\Diactoros\\Stream')) {
36
                return new \Zend\Diactoros\Stream($file, $mode);
37
            }
38
39
            throw new \RuntimeException('Unable to create a stream. No stream factory defined');
40
        }
41
42
        return call_user_func(self::$streamFactory, $file, $mode);
43
    }
44
45
    /**
46
     * Create instances of the middlewares.
47
     *
48
     * @param string $name
49
     * @param array  $args
50
     */
51
    public static function __callStatic($name, $args)
52
    {
53
        $class = __NAMESPACE__.'\\Middleware\\'.ucfirst($name);
54
55
        if (class_exists($class)) {
56
            switch (count($args)) {
57
                case 0:
58
                    return new $class();
59
60
                case 1:
61
                    return new $class($args[0]);
62
63
                default:
64
                    return (new \ReflectionClass($class))->newInstanceArgs($args);
65
            }
66
        }
67
68
        throw new RuntimeException("The middleware {$name} does not exits");
69
    }
70
71
    /**
72
     * Create a middleware callable that acts as a "proxy" to a real middleware that must be returned by the given callback.
73
     *
74
     * @param callable $factory Takes no argument and MUST return a middleware callable or false
75
     * 
76
     * @return callable
77
     */
78
    public static function create(callable $factory)
79
    {
80
        return function (RequestInterface $request, ResponseInterface $response, callable $next) use ($factory) {
81
            $middleware = $factory();
82
83
            if ($middleware === false) {
84
                return $next($request, $response);
85
            }
86
87
            if (!is_callable($middleware)) {
88
                throw new RuntimeException(sprintf('Factory returned "%s" instead of a callable or FALSE.', gettype($middleware)));
89
            }
90
91
            return $middleware($request, $response, $next);
92
        };
93
    }
94
95
    /**
96
     * Store an attribute in the request.
97
     *
98
     * @param ServerRequestInterface $request
99
     * @param string                 $name
100
     * @param mixed                  $value
101
     *
102
     * @return ServerRequestInterface
103
     */
104
    public static function setAttribute(ServerRequestInterface $request, $name, $value)
105
    {
106
        $attributes = $request->getAttribute(self::KEY, []);
107
        $attributes[$name] = $value;
108
109
        return $request->withAttribute(self::KEY, $attributes);
110
    }
111
112
    /**
113
     * Retrieves an attribute from the request.
114
     *
115
     * @param ServerRequestInterface $request
116
     * @param string                 $name
117
     *
118
     * @return mixed
119
     */
120
    public static function getAttribute(ServerRequestInterface $request, $name)
121
    {
122
        $attributes = $request->getAttribute(self::KEY);
123
124
        if (isset($attributes[$name])) {
125
            return $attributes[$name];
126
        }
127
    }
128
129
    /**
130
     * Check whether an attribute exists.
131
     *
132
     * @param ServerRequestInterface $request
133
     * @param string                 $name
134
     *
135
     * @return bool
136
     */
137
    public static function hasAttribute(ServerRequestInterface $request, $name)
138
    {
139
        $attributes = $request->getAttribute(self::KEY);
140
141
        if (empty($attributes)) {
142
            return false;
143
        }
144
145
        return array_key_exists($name, $attributes);
146
    }
147
}
148