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

api-platform / core / 17738646910

15 Sep 2025 03:40PM UTC coverage: 22.156% (-0.07%) from 22.227%
17738646910

Pull #7380

github

web-flow
Merge e3d95e940 into 4abec444e
Pull Request #7380: fix(laravel): http cache compatibility

0 of 152 new or added lines in 9 files covered. (0.0%)

4 existing lines in 4 files now uncovered.

11127 of 50221 relevant lines covered (22.16%)

23.41 hits per line

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

0.0
/src/Laravel/Controller/ApiPlatformController.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\Laravel\Controller;
15

16
use ApiPlatform\HttpCache\PurgerInterface;
17
use ApiPlatform\Laravel\Eloquent\Listener\PurgeHttpCacheListener;
18
use ApiPlatform\Metadata\HttpOperation;
19
use ApiPlatform\Metadata\Operation\Factory\OperationMetadataFactoryInterface;
20
use ApiPlatform\State\ProcessorInterface;
21
use ApiPlatform\State\ProviderInterface;
22
use Illuminate\Http\Request;
23
use Illuminate\Routing\Controller;
24
use Illuminate\Support\Facades\Event;
25
use Symfony\Component\HttpFoundation\Response;
26

27
class ApiPlatformController extends Controller
28
{
29
    /**
30
     * @param ProviderInterface<object>                                  $provider
31
     * @param ProcessorInterface<iterable<object>|object|null, Response> $processor
32
     */
33
    public function __construct(
34
        protected OperationMetadataFactoryInterface $operationMetadataFactory,
35
        protected ProviderInterface $provider,
36
        protected ProcessorInterface $processor,
37
    ) {
38
    }
×
39

40
    /**
41
     * Display a listing of the resource.
42
     */
43
    public function __invoke(Request $request): Response
44
    {
45
        $operation = $request->attributes->get('_api_operation');
×
46
        if (!$operation) {
×
47
            throw new \RuntimeException('Operation not found.');
×
48
        }
49

50
        if (!$operation instanceof HttpOperation) {
×
51
            throw new \LogicException('Operation is not an HttpOperation.');
×
52
        }
53

54
        $uriVariables = $this->getUriVariables($request, $operation);
×
55
        $request->attributes->set('_api_uri_variables', $uriVariables);
×
56
        // at some point we could introduce that back
57
        // if ($this->uriVariablesConverter) {
58
        //     $context = ['operation' => $operation, 'uri_variables_map' => $uriVariablesMap];
59
        //     $identifiers = $this->uriVariablesConverter->convert($identifiers, $operation->getClass() ?? $resourceClass, $context);
60
        // }
61

62
        $context = [
×
63
            'request' => $request,
×
64
            'uri_variables' => $uriVariables,
×
65
            'resource_class' => $operation->getClass(),
×
66
        ];
×
67

68
        if (null === $operation->canValidate()) {
×
69
            $operation = $operation->withValidate(!$request->isMethodSafe() && !$request->isMethod('DELETE'));
×
70
        }
71

72
        if (null === $operation->canRead()) {
×
73
            $operation = $operation->withRead($operation->getUriVariables() || $request->isMethodSafe());
×
74
        }
75

76
        if (null === $operation->canDeserialize()) {
×
77
            $operation = $operation->withDeserialize(\in_array($operation->getMethod(), ['POST', 'PUT', 'PATCH'], true));
×
78
        }
79

80
        $body = $this->provider->provide($operation, $uriVariables, $context);
×
81

82
        // The provider can change the Operation, extract it again from the Request attributes
83
        if ($request->attributes->get('_api_operation') !== $operation) {
×
84
            $operation = $request->attributes->get('_api_operation');
×
85
            $uriVariables = $this->getUriVariables($request, $operation);
×
86
        }
87

88
        $context['previous_data'] = $request->attributes->get('previous_data');
×
89
        $context['data'] = $request->attributes->get('data');
×
90

91
        if (null === $operation->canWrite()) {
×
92
            $operation = $operation->withWrite(!$request->isMethodSafe());
×
93
        }
94

95
        if (null === $operation->canSerialize()) {
×
96
            $operation = $operation->withSerialize(true);
×
97
        }
98

NEW
99
        if (interface_exists(PurgerInterface::class)) {
×
NEW
100
            Event::listen('eloquent.saved: *', [PurgeHttpCacheListener::class, 'handleModelSaved']);
×
NEW
101
            Event::listen('eloquent.deleted: *', [PurgeHttpCacheListener::class, 'handleModelDeleted']);
×
102
        }
103

UNCOV
104
        return $this->processor->process($body, $operation, $uriVariables, $context);
×
105
    }
106

107
    /**
108
     * @return array<string, mixed>
109
     */
110
    private function getUriVariables(Request $request, HttpOperation $operation): array
111
    {
112
        $uriVariables = [];
×
113
        foreach ($operation->getUriVariables() ?? [] as $parameterName => $_) {
×
114
            $parameter = $request->route($parameterName);
×
115
            if (\is_string($parameter) && ($format = $request->attributes->get('_format')) && str_contains($parameter, $format)) {
×
116
                $parameter = substr($parameter, 0, \strlen($parameter) - (\strlen($format) + 1));
×
117
            }
118

119
            $uriVariables[(string) $parameterName] = $parameter;
×
120
        }
121

122
        return $uriVariables;
×
123
    }
124
}
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