Issues (332)

Bridge/Symfony/Routing/OperationMethodResolver.php (1 issue)

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\Bridge\Symfony\Routing;
15
16
use ApiPlatform\Core\Api\OperationType;
17
use ApiPlatform\Core\Exception\RuntimeException;
18
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
19
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
20
use Symfony\Component\Routing\Route;
21
use Symfony\Component\Routing\RouterInterface;
22
23
/**
24
 * Resolves the HTTP method associated with an operation, extended for Symfony routing.
25
 *
26
 * @author Kévin Dunglas <[email protected]>
27
 * @author Teoh Han Hui <[email protected]>
28
 *
29
 * @deprecated since API Platform 2.5, use the "method" attribute instead
30
 */
31
final class OperationMethodResolver implements OperationMethodResolverInterface
0 ignored issues
show
Deprecated Code introduced by
The interface ApiPlatform\Core\Bridge\...MethodResolverInterface has been deprecated: since API Platform 2.5, use the "method" attribute instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

31
final class OperationMethodResolver implements /** @scrutinizer ignore-deprecated */ OperationMethodResolverInterface

This interface has been deprecated. The supplier of the interface has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.

Loading history...
32
{
33
    private $router;
34
    private $resourceMetadataFactory;
35
36
    public function __construct(RouterInterface $router, ResourceMetadataFactoryInterface $resourceMetadataFactory)
37
    {
38
        @trigger_error(sprintf('The "%s" class is deprecated since API Platform 2.5, use the "method" attribute instead.', __CLASS__), E_USER_DEPRECATED);
39
40
        $this->router = $router;
41
        $this->resourceMetadataFactory = $resourceMetadataFactory;
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public function getCollectionOperationMethod(string $resourceClass, string $operationName): string
48
    {
49
        return $this->getOperationMethod($resourceClass, $operationName, OperationType::COLLECTION);
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function getItemOperationMethod(string $resourceClass, string $operationName): string
56
    {
57
        return $this->getOperationMethod($resourceClass, $operationName, OperationType::ITEM);
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function getCollectionOperationRoute(string $resourceClass, string $operationName): Route
64
    {
65
        return $this->getOperationRoute($resourceClass, $operationName, OperationType::COLLECTION);
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function getItemOperationRoute(string $resourceClass, string $operationName): Route
72
    {
73
        return $this->getOperationRoute($resourceClass, $operationName, OperationType::ITEM);
74
    }
75
76
    /**
77
     * @throws RuntimeException
78
     */
79
    private function getOperationMethod(string $resourceClass, string $operationName, string $operationType): string
80
    {
81
        $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
82
83
        if (OperationType::ITEM === $operationType) {
84
            $method = $resourceMetadata->getItemOperationAttribute($operationName, 'method');
85
        } else {
86
            $method = $resourceMetadata->getCollectionOperationAttribute($operationName, 'method');
87
        }
88
89
        if (null !== $method) {
90
            return strtoupper($method);
91
        }
92
93
        if (null === $routeName = $this->getRouteName($resourceMetadata, $operationName, $operationType)) {
94
            throw new RuntimeException(sprintf('Either a "route_name" or a "method" operation attribute must exist for the operation "%s" of the resource "%s".', $operationName, $resourceClass));
95
        }
96
97
        return $this->getRoute($routeName)->getMethods()[0] ?? 'GET';
98
    }
99
100
    /**
101
     * Gets the route related to the given operation.
102
     *
103
     * @throws RuntimeException
104
     */
105
    private function getOperationRoute(string $resourceClass, string $operationName, string $operationType): Route
106
    {
107
        $routeName = $this->getRouteName($this->resourceMetadataFactory->create($resourceClass), $operationName, $operationType);
108
        if (null !== $routeName) {
109
            return $this->getRoute($routeName);
110
        }
111
112
        $operationNameKey = sprintf('_api_%s_operation_name', $operationType);
113
114
        foreach ($this->router->getRouteCollection()->all() as $routeName => $route) {
115
            $currentResourceClass = $route->getDefault('_api_resource_class');
116
            $currentOperationName = $route->getDefault($operationNameKey);
117
118
            if ($resourceClass === $currentResourceClass && $operationName === $currentOperationName) {
119
                return $route;
120
            }
121
        }
122
123
        throw new RuntimeException(sprintf('No route found for operation "%s" for type "%s".', $operationName, $resourceClass));
124
    }
125
126
    /**
127
     * Gets the route name or null if not defined.
128
     */
129
    private function getRouteName(ResourceMetadata $resourceMetadata, string $operationName, string $operationType): ?string
130
    {
131
        if (OperationType::ITEM === $operationType) {
132
            return $resourceMetadata->getItemOperationAttribute($operationName, 'route_name');
133
        }
134
135
        return $resourceMetadata->getCollectionOperationAttribute($operationName, 'route_name');
136
    }
137
138
    /**
139
     * Gets the route with the given name.
140
     *
141
     * @throws RuntimeException
142
     */
143
    private function getRoute(string $routeName): Route
144
    {
145
        foreach ($this->router->getRouteCollection() as $name => $route) {
146
            if ($routeName === $name) {
147
                return $route;
148
            }
149
        }
150
151
        throw new RuntimeException(sprintf('The route "%s" does not exist.', $routeName));
152
    }
153
}
154