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

api-platform / core / 3712739783

pending completion
3712739783

Pull #5254

github

GitHub
Merge 9dfa88fa6 into ac711530f
Pull Request #5254: [OpenApi] Add ApiResource::openapi and deprecate openapiContext

199 of 199 new or added lines in 6 files covered. (100.0%)

7494 of 12363 relevant lines covered (60.62%)

67.55 hits per line

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

82.93
/src/Symfony/EventListener/SerializeListener.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\Exception\RuntimeException;
17
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
18
use ApiPlatform\Serializer\ResourceList;
19
use ApiPlatform\Serializer\SerializerContextBuilderInterface;
20
use ApiPlatform\Util\OperationRequestInitiatorTrait;
21
use ApiPlatform\Util\RequestAttributesExtractor;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpFoundation\Response;
24
use Symfony\Component\HttpKernel\Event\ViewEvent;
25
use Symfony\Component\Serializer\Encoder\EncoderInterface;
26
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
27
use Symfony\Component\Serializer\SerializerInterface;
28
use Symfony\Component\WebLink\GenericLinkProvider;
29
use Symfony\Component\WebLink\Link;
30

31
/**
32
 * Serializes data.
33
 *
34
 * @author Kévin Dunglas <dunglas@gmail.com>
35
 */
36
final class SerializeListener
37
{
38
    use OperationRequestInitiatorTrait;
39

40
    public const OPERATION_ATTRIBUTE_KEY = 'serialize';
41

42
    public function __construct(private readonly SerializerInterface $serializer, private readonly SerializerContextBuilderInterface $serializerContextBuilder, ?ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory = null)
43
    {
44
        $this->resourceMetadataCollectionFactory = $resourceMetadataFactory;
459✔
45
    }
46

47
    /**
48
     * Serializes the data to the requested format.
49
     */
50
    public function onKernelView(ViewEvent $event): void
51
    {
52
        $controllerResult = $event->getControllerResult();
459✔
53
        $request = $event->getRequest();
459✔
54

55
        if ($controllerResult instanceof Response) {
459✔
56
            return;
×
57
        }
58

59
        $attributes = RequestAttributesExtractor::extractAttributes($request);
459✔
60

61
        if (!($attributes['respond'] ?? $request->attributes->getBoolean('_api_respond', false))) {
459✔
62
            return;
1✔
63
        }
64

65
        $operation = $this->initializeOperation($request);
458✔
66
        if (!($operation?->canSerialize() ?? true)) {
458✔
67
            return;
×
68
        }
69

70
        if (!$attributes) {
458✔
71
            $this->serializeRawData($event, $request, $controllerResult);
17✔
72

73
            return;
17✔
74
        }
75

76
        $context = $this->serializerContextBuilder->createFromRequest($request, true, $attributes);
441✔
77
        if (isset($context['output']) && \array_key_exists('class', $context['output']) && null === $context['output']['class']) {
441✔
78
            $event->setControllerResult(null);
2✔
79

80
            return;
2✔
81
        }
82

83
        if ($included = $request->attributes->get('_api_included')) {
439✔
84
            $context['api_included'] = $included;
16✔
85
        }
86
        $resources = new ResourceList();
439✔
87
        $context['resources'] = &$resources;
439✔
88
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'resources';
439✔
89

90
        $resourcesToPush = new ResourceList();
439✔
91
        $context['resources_to_push'] = &$resourcesToPush;
439✔
92
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'resources_to_push';
439✔
93

94
        $request->attributes->set('_api_normalization_context', $context);
439✔
95
        $event->setControllerResult($this->serializer->serialize($controllerResult, $request->getRequestFormat(), $context));
439✔
96

97
        $request->attributes->set('_resources', $request->attributes->get('_resources', []) + (array) $resources);
439✔
98
        if (!\count($resourcesToPush)) {
439✔
99
            return;
439✔
100
        }
101

102
        $linkProvider = $request->attributes->get('_links', new GenericLinkProvider());
×
103
        foreach ($resourcesToPush as $resourceToPush) {
×
104
            $linkProvider = $linkProvider->withLink((new Link('preload', $resourceToPush))->withAttribute('as', 'fetch'));
×
105
        }
106
        $request->attributes->set('_links', $linkProvider);
×
107
    }
108

109
    /**
110
     * Tries to serialize data that are not API resources (e.g. the entrypoint or data returned by a custom controller).
111
     *
112
     * @throws RuntimeException
113
     */
114
    private function serializeRawData(ViewEvent $event, Request $request, $controllerResult): void
115
    {
116
        if (\is_object($controllerResult)) {
17✔
117
            $event->setControllerResult($this->serializer->serialize($controllerResult, $request->getRequestFormat(), $request->attributes->get('_api_normalization_context', [])));
11✔
118

119
            return;
11✔
120
        }
121

122
        if (!$this->serializer instanceof EncoderInterface) {
6✔
123
            throw new RuntimeException(sprintf('The serializer must implement the "%s" interface.', EncoderInterface::class));
×
124
        }
125

126
        $event->setControllerResult($this->serializer->encode($controllerResult, $request->getRequestFormat()));
6✔
127
    }
128
}
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

© 2025 Coveralls, Inc