Passed
Branch master (7c3f6c)
by Javi
02:38
created

ResultConverter   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 5
dl 0
loc 85
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A attribute() 0 6 1
A converter() 0 6 1
D process() 0 36 10
1
<?php
2
3
namespace itsjavi\Flatdown\Middlewares;
4
5
use FastRoute\Dispatcher as FastRouteDispatcher;
6
use Interop\Http\ServerMiddleware\DelegateInterface;
7
use Interop\Http\ServerMiddleware\MiddlewareInterface;
8
use Middlewares\Utils;
9
use Psr\Http\Message\ResponseInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
12
/**
13
 * Wraps the request handler callback in another one that will
14
 * try to convert the handler result into a string.
15
 *
16
 * By default arrays and objects will be converted to JSON.
17
 *
18
 */
19
class ResultConverter implements MiddlewareInterface
20
{
21
    /**
22
     * @var string Attribute name for handler reference
23
     */
24
    private $attribute = 'request-handler';
25
26
    /**
27
     * @var callable Converter for non scalar values
28
     */
29
    private $converter;
30
31
    /**
32
     * Set the attribute name to store handler reference.
33
     *
34
     * @param string $attribute
35
     *
36
     * @return self
37
     */
38
    public function attribute($attribute)
39
    {
40
        $this->attribute = $attribute;
41
42
        return $this;
43
    }
44
45
    /**
46
     * Replaces the default converter
47
     *
48
     * @param callable $converter Converter for non scalar values
49
     *
50
     * @return self
51
     */
52
    public function converter(callable $converter)
53
    {
54
        $this->converter = $converter;
55
56
        return $this;
57
    }
58
59
    /**
60
     * Process a server request and return a response.
61
     *
62
     * @param ServerRequestInterface $request
63
     * @param DelegateInterface $delegate
64
     *
65
     * @return ResponseInterface
66
     */
67
    public function process(ServerRequestInterface $request, DelegateInterface $delegate)
68
    {
69
        $handler = $request->getAttribute($this->attribute);
70
71
        if (!is_callable($handler)) {
72
            return $delegate->process($request);
73
        }
74
75
        $converter = $this->converter ?: function ($value) {
76
            if ((is_array($value) || is_object($value)) && !($value instanceof \Closure)) {
77
                $response = Utils\Factory::createResponse(200);
78
                $response->getBody()->write(json_encode($value));
79
80
                return $response->withHeader('content-type', 'application/json');
81
            }
82
            throw new \RuntimeException("Incompatible return value returned in the route handler.");
83
        };
84
85
        $handlerWrapper = function (ServerRequestInterface $request, ...$args) use ($handler, $converter) {
86
            $result = call_user_func($handler, $request, ...$args);
87
88
            if (($result instanceof ResponseInterface) || is_scalar($result)) {
89
                return $result;
90
            }
91
92
            if (is_object($result) && method_exists($result, '__toString')) {
93
                return $result->__toString();
94
            }
95
96
            return $converter($result);
97
        };
98
99
        $request = $request->withAttribute($this->attribute, $handlerWrapper);
100
101
        return $delegate->process($request);
102
    }
103
}
104