Passed
Push — master ( 8bd912...d93388 )
by Alan
06:58 queued 02:20
created

src/EventListener/RespondListener.php (2 issues)

1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\EventListener;
15
16
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
17
use ApiPlatform\Core\Util\RequestAttributesExtractor;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
20
21
/**
22
 * Builds the response object.
23
 *
24
 * @author Kévin Dunglas <[email protected]>
25
 */
26
final class RespondListener
27
{
28
    public const METHOD_TO_CODE = [
29
        'POST' => Response::HTTP_CREATED,
30
        'DELETE' => Response::HTTP_NO_CONTENT,
31
    ];
32
33
    private $resourceMetadataFactory;
34
35
    public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory = null)
36
    {
37
        $this->resourceMetadataFactory = $resourceMetadataFactory;
38
    }
39
40
    /**
41
     * Creates a Response to send to the client according to the requested format.
42
     */
43
    public function onKernelView(GetResponseForControllerResultEvent $event): void
44
    {
45
        $controllerResult = $event->getControllerResult();
46
        $request = $event->getRequest();
47
48
        $attributes = RequestAttributesExtractor::extractAttributes($request);
49
        if ($controllerResult instanceof Response && ($attributes['respond'] ?? false)) {
50
            $event->setResponse($controllerResult);
51
52
            return;
53
        }
54
        if ($controllerResult instanceof Response || !($attributes['respond'] ?? $request->attributes->getBoolean('_api_respond', false))) {
55
            return;
56
        }
57
58
        $headers = [
59
            'Content-Type' => sprintf('%s; charset=utf-8', $request->getMimeType($request->getRequestFormat())),
60
            'Vary' => 'Accept',
61
            'X-Content-Type-Options' => 'nosniff',
62
            'X-Frame-Options' => 'deny',
63
        ];
64
65
        if ($request->attributes->has('_api_write_item_iri')) {
66
            $headers['Content-Location'] = $request->attributes->get('_api_write_item_iri');
67
68
            if ($request->isMethod('POST')) {
69
                $headers['Location'] = $request->attributes->get('_api_write_item_iri');
70
            }
71
        }
72
73
        $status = null;
74
        if ($this->resourceMetadataFactory && $attributes) {
0 ignored issues
show
$attributes is an empty array, thus is always false.
Loading history...
Bug Best Practice introduced by
The expression $attributes of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
75
            $resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);
76
77
            if ($sunset = $resourceMetadata->getOperationAttribute($attributes, 'sunset', null, true)) {
78
                $headers['Sunset'] = (new \DateTimeImmutable($sunset))->format(\DateTime::RFC1123);
79
            }
80
81
            $status = $resourceMetadata->getOperationAttribute($attributes, 'status');
82
        }
83
84
        $event->setResponse(new Response(
85
            $controllerResult,
86
            $status ?? self::METHOD_TO_CODE[$request->getMethod()] ?? Response::HTTP_OK,
87
            $headers
88
        ));
89
    }
90
}
91