Passed
Push — master ( a81739...b2df95 )
by Felipe
03:33 queued 01:40
created

JsonpCallbackMiddleware::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 2
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of coisa/http.
4
 *
5
 * (c) Felipe Sayão Lobato Abreu <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace CoiSA\Http\Middleware;
12
13
use CoiSA\Http\Message\StreamFactory;
14
use Psr\Http\Message\ResponseInterface;
15
use Psr\Http\Message\ServerRequestInterface;
16
use Psr\Http\Message\StreamFactoryInterface;
17
use Psr\Http\Server\MiddlewareInterface;
18
use Psr\Http\Server\RequestHandlerInterface;
19
20
/**
21
 * Class JsonpCallbackMiddleware
22
 *
23
 * @package CoiSA\Http\Middleware
24
 */
25
final class JsonpCallbackMiddleware implements MiddlewareInterface
26
{
27
    /**
28
     * @const string
29
     */
30
    const REQUEST_QUERY_PARAM = 'callback';
31
32
    /**
33
     * @const string
34
     */
35
    const REQUEST_ACCEPT_HEADER = 'text/javascript';
36
37
    /**
38
     * @var string
39
     */
40
    private $queryParam;
41
42
    /**
43
     * @var StreamFactoryInterface
44
     */
45
    private $streamFactory;
46
47
    /**
48
     * JsonpCallbackMiddleware constructor.
49
     *
50
     * @param string $queryParam
51
     * @param StreamFactoryInterface|null $streamFactory
52
     */
53
    public function __construct(string $queryParam = self::REQUEST_QUERY_PARAM, StreamFactoryInterface $streamFactory = null)
54
    {
55
        $this->queryParam    = $queryParam;
56
        $this->streamFactory = $streamFactory ?? new StreamFactory();
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
63
    {
64
        $response = $handler->handle($request);
65
        $callback = $request->getQueryParams()[$this->queryParam] ?? false;
66
67
        if (!$callback) {
68
            return $response;
69
        }
70
71
        if ($request->hasHeader('Accept')
72
            && !in_array(self::REQUEST_ACCEPT_HEADER, $request->getHeader('Accept'))
73
        ) {
74
            return $response;
75
        }
76
77
        // @TODO accept all types of json content-type ['application/json', 'text/json', 'application/x-json'];
78
79
        if ($response->hasHeader('Content-Type')
80
            && !in_array('application/json', $response->getHeader('Content-Type'))
81
        ) {
82
            return $response;
83
        }
84
85
        $content = \htmlspecialchars($callback) . '(' . $response->getBody() . ');';
86
        $body    = $this->streamFactory->createStream($content);
87
88
        return $response
89
            ->withHeader('Content-Type', 'text/javascript')
90
            ->withBody($body);
91
    }
92
}
93