Completed
Push — master ( e81b92...349f3b )
by Phil
58:34 queued 08:42
created

src/Strategy/JsonStrategy.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php declare(strict_types=1);
2
3
namespace League\Route\Strategy;
4
5
use Exception;
6
use League\Route\{ContainerAwareInterface, ContainerAwareTrait};
7
use League\Route\Http\Exception as HttpException;
8
use League\Route\Http\Exception\{MethodNotAllowedException, NotFoundException};
9
use League\Route\Route;
10
use Psr\Http\Message\{ResponseFactoryInterface, ResponseInterface, ServerRequestInterface};
11
use Psr\Http\Server\{MiddlewareInterface, RequestHandlerInterface};
12
13
class JsonStrategy implements ContainerAwareInterface, StrategyInterface
14
{
15
    use ContainerAwareTrait;
16
17
    /**
18
     * @var \Psr\Http\Message\ResponseFactoryInterface
19
     */
20
    protected $responseFactory;
21
22
    /**
23
     * Construct.
24
     *
25
     * @param \Psr\Http\Message\ResponseFactoryInterface $responseFactory
26
     */
27 28
    public function __construct(ResponseFactoryInterface $responseFactory)
28
    {
29 28
        $this->responseFactory = $responseFactory;
30 28
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35 14
    public function invokeRouteCallable(Route $route, ServerRequestInterface $request) : ResponseInterface
36
    {
37 14
        $controller = $route->getCallable($this->getContainer());
38 14
        $response = $controller($request, $route->getVars());
39
40 10
        if ($this->isJsonEncodable($response)) {
41 8
            $body     = json_encode($response);
42 8
            $response = $this->responseFactory->createResponse();
43 8
            $response = $response->withStatus(200);
44 8
            $response->getBody()->write($body);
45
        }
46
47 10
        if ($response instanceof ResponseInterface && ! $response->hasHeader('content-type')) {
0 ignored issues
show
The class Psr\Http\Message\ResponseInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
48 10
            $response = $response->withAddedHeader('content-type', 'application/json');
49
        }
50
51 10
        return $response;
52
    }
53
54
    /**
55
     * Check if the response can be converted to JSON
56
     *
57
     * Arrays can always be converted, objects can be converted if they're not a response already
58
     *
59
     * @param mixed $response
60
     *
61
     * @return bool
62
     */
63 10
    protected function isJsonEncodable($response) : bool
64
    {
65 10
        if ($response instanceof ResponseInterface) {
66 2
            return false;
67
        }
68
69 8
        return (is_array($response) || is_object($response));
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 4
    public function getNotFoundDecorator(NotFoundException $exception) : MiddlewareInterface
76
    {
77 4
        return $this->buildJsonResponseMiddleware($exception);
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83 4
    public function getMethodNotAllowedDecorator(MethodNotAllowedException $exception) : MiddlewareInterface
84
    {
85 4
        return $this->buildJsonResponseMiddleware($exception);
86
    }
87
88
    /**
89
     * Return a middleware the creates a JSON response from an HTTP exception
90
     *
91
     * @param \League\Route\Http\Exception $exception
92
     *
93
     * @return \Psr\Http\Server\MiddlewareInterface
94
     */
95 8
    protected function buildJsonResponseMiddleware(HttpException $exception) : MiddlewareInterface
96
    {
97
        return new class($this->responseFactory->createResponse(), $exception) implements MiddlewareInterface
98
        {
99
            protected $response;
100
            protected $exception;
101
102
            public function __construct(ResponseInterface $response, HttpException $exception)
103
            {
104 8
                $this->response  = $response;
105 8
                $this->exception = $exception;
106 8
            }
107
108
            public function process(
109
                ServerRequestInterface $request,
110
                RequestHandlerInterface $requestHandler
111
            ) : ResponseInterface {
112 8
                return $this->exception->buildJsonResponse($this->response);
113
            }
114
        };
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function getExceptionHandler() : MiddlewareInterface
121
    {
122
        return new class($this->responseFactory->createResponse()) implements MiddlewareInterface
123
        {
124
            protected $response;
125
126 12
            public function __construct(ResponseInterface $response)
127
            {
128 12
                $this->response = $response;
129 12
            }
130
131 12
            public function process(
132
                ServerRequestInterface $request,
133
                RequestHandlerInterface $requestHandler
134
            ) : ResponseInterface {
135
                try {
136 12
                    return $requestHandler->handle($request);
137 8
                } catch (Exception $exception) {
138 8
                    $response = $this->response;
139
140 8
                    if ($exception instanceof HttpException) {
141 4
                        return $exception->buildJsonResponse($response);
142
                    }
143
144 4
                    $response->getBody()->write(json_encode([
145 4
                        'status_code'   => 500,
146 4
                        'reason_phrase' => $exception->getMessage()
147
                    ]));
148
149 4
                    $response = $response->withAddedHeader('content-type', 'application/json');
150 4
                    return $response->withStatus(500, strtok($exception->getMessage(), "\n"));
151
                }
152
            }
153
        };
154
    }
155
}
156