• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 7970407897

20 Feb 2024 08:20AM UTC coverage: 66.686% (+0.003%) from 66.683%
7970407897

push

github

web-flow
fix(openapi): skip requestBody if input is false (#6163)

* fix(openapi): skip requestBody if input is false

* cs fix

* fix phpstan error

* cs fix

* merge condition

---------

Co-authored-by: soyuka <soyuka@users.noreply.github.com>

2 of 2 new or added lines in 1 file covered. (100.0%)

86 existing lines in 9 files now uncovered.

16306 of 24452 relevant lines covered (66.69%)

37.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.37
/src/Symfony/EventListener/RespondListener.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
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\Symfony\EventListener;
15

16
use ApiPlatform\Api\IriConverterInterface as LegacyIriConverterInterface;
17
use ApiPlatform\Metadata\Exception\HttpExceptionInterface;
18
use ApiPlatform\Metadata\IriConverterInterface;
19
use ApiPlatform\Metadata\Put;
20
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
21
use ApiPlatform\Metadata\UrlGeneratorInterface;
22
use ApiPlatform\State\Util\OperationRequestInitiatorTrait;
23
use ApiPlatform\Symfony\Util\RequestAttributesExtractor;
24
use Symfony\Component\HttpFoundation\Response;
25
use Symfony\Component\HttpKernel\Event\ViewEvent;
26

27
/**
28
 * Builds the response object.
29
 *
30
 * @author Kévin Dunglas <dunglas@gmail.com>
31
 */
32
final class RespondListener
33
{
34
    use OperationRequestInitiatorTrait;
35

36
    public const METHOD_TO_CODE = [
37
        'POST' => Response::HTTP_CREATED,
38
        'DELETE' => Response::HTTP_NO_CONTENT,
39
    ];
40

41
    public function __construct(
42
        ?ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory = null,
43
        private readonly IriConverterInterface|LegacyIriConverterInterface|null $iriConverter = null,
44
    ) {
45
        $this->resourceMetadataCollectionFactory = $resourceMetadataFactory;
60✔
46
    }
47

48
    /**
49
     * Creates a Response to send to the client according to the requested format.
50
     */
51
    public function onKernelView(ViewEvent $event): void
52
    {
53
        $request = $event->getRequest();
60✔
54
        $controllerResult = $event->getControllerResult();
60✔
55
        $operation = $this->initializeOperation($request);
60✔
56

57
        if ('api_platform.symfony.main_controller' === $operation?->getController() || $request->attributes->get('_api_platform_disable_listeners')) {
60✔
58
            return;
×
59
        }
60

61
        $attributes = RequestAttributesExtractor::extractAttributes($request);
60✔
62

63
        if ($controllerResult instanceof Response && ($attributes['respond'] ?? false)) {
60✔
64
            $event->setResponse($controllerResult);
4✔
65

66
            return;
4✔
67
        }
68

69
        if ($controllerResult instanceof Response || !($attributes['respond'] ?? $request->attributes->getBoolean('_api_respond'))) {
56✔
70
            return;
8✔
71
        }
72

73
        $headers = [
48✔
74
            'Content-Type' => sprintf('%s; charset=utf-8', $request->getMimeType($request->getRequestFormat())),
48✔
75
            'Vary' => 'Accept',
48✔
76
            'X-Content-Type-Options' => 'nosniff',
48✔
77
            'X-Frame-Options' => 'deny',
48✔
78
        ];
48✔
79

80
        $status = $operation?->getStatus();
48✔
81

82
        if ($sunset = $operation?->getSunset()) {
48✔
83
            $headers['Sunset'] = (new \DateTimeImmutable($sunset))->format(\DateTime::RFC1123);
4✔
84
        }
85

86
        if ($acceptPatch = $operation?->getAcceptPatch()) {
48✔
UNCOV
87
            $headers['Accept-Patch'] = $acceptPatch;
5✔
88
        }
89

90
        $method = $request->getMethod();
48✔
91
        if (
92
            $this->iriConverter
48✔
93
            && $operation
94
            && ($operation->getExtraProperties()['is_alternate_resource_metadata'] ?? false)
48✔
95
            && 301 === $operation->getStatus()
48✔
96
        ) {
97
            $status = 301;
×
98
            $headers['Location'] = $this->iriConverter->getIriFromResource($request->attributes->get('data'), UrlGeneratorInterface::ABS_PATH, $operation);
×
99
        } elseif ('PUT' === $method && !($attributes['previous_data'] ?? null) && null === $status && ($operation instanceof Put && ($operation->getAllowCreate() ?? false))) {
48✔
100
            $status = Response::HTTP_CREATED;
×
101
        }
102

103
        $status ??= self::METHOD_TO_CODE[$request->getMethod()] ?? Response::HTTP_OK;
48✔
104

105
        if ($request->attributes->has('_api_write_item_iri')) {
48✔
106
            $headers['Content-Location'] = $request->attributes->get('_api_write_item_iri');
15✔
107

108
            if ((Response::HTTP_CREATED === $status || (300 <= $status && $status < 400)) && 'POST' === $method) {
15✔
109
                $headers['Location'] = $request->attributes->get('_api_write_item_iri');
11✔
110
            }
111
        }
112

113
        if (($exception = $request->attributes->get('data')) instanceof HttpExceptionInterface) {
48✔
114
            $headers = array_merge($headers, $exception->getHeaders());
×
115
        }
116

117
        $event->setResponse(new Response(
48✔
118
            $controllerResult,
48✔
119
            $status,
48✔
120
            $headers
48✔
121
        ));
48✔
122
    }
123
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc