15
15
16
16
use ApiPlatform \Core \DataProvider \CollectionDataProviderInterface ;
17
17
use ApiPlatform \Core \DataProvider \ItemDataProviderInterface ;
18
- use ApiPlatform \Core \DataProvider \OperationDataProviderTrait ;
19
18
use ApiPlatform \Core \DataProvider \SubresourceDataProviderInterface ;
20
- use ApiPlatform \Core \Exception \InvalidIdentifierException ;
21
- use ApiPlatform \Core \Exception \RuntimeException ;
19
+ use ApiPlatform \Core \Exception \NotFoundException ;
22
20
use ApiPlatform \Core \Identifier \IdentifierConverterInterface ;
23
21
use ApiPlatform \Core \Metadata \Resource \Factory \ResourceMetadataFactoryInterface ;
24
- use ApiPlatform \Core \Metadata \Resource \ToggleableOperationAttributeTrait ;
25
22
use ApiPlatform \Core \Serializer \SerializerContextBuilderInterface ;
23
+ use ApiPlatform \Core \Stage \ReadStage ;
24
+ use ApiPlatform \Core \Stage \ReadStageInterface ;
26
25
use ApiPlatform \Core \Util \RequestAttributesExtractor ;
27
26
use ApiPlatform \Core \Util \RequestParser ;
28
27
use Symfony \Component \HttpKernel \Event \GetResponseEvent ;
35
34
*/
36
35
final class ReadListener
37
36
{
38
- use OperationDataProviderTrait;
39
- use ToggleableOperationAttributeTrait;
40
-
41
37
public const OPERATION_ATTRIBUTE_KEY = 'read ' ;
42
38
43
39
private $ serializerContextBuilder ;
40
+ private $ readStage ;
44
41
45
- public function __construct (CollectionDataProviderInterface $ collectionDataProvider , ItemDataProviderInterface $ itemDataProvider , SubresourceDataProviderInterface $ subresourceDataProvider = null , SerializerContextBuilderInterface $ serializerContextBuilder = null , IdentifierConverterInterface $ identifierConverter = null , ResourceMetadataFactoryInterface $ resourceMetadataFactory = null )
42
+ public function __construct (CollectionDataProviderInterface $ collectionDataProvider , ItemDataProviderInterface $ itemDataProvider , SubresourceDataProviderInterface $ subresourceDataProvider = null , SerializerContextBuilderInterface $ serializerContextBuilder = null , IdentifierConverterInterface $ identifierConverter = null , ResourceMetadataFactoryInterface $ resourceMetadataFactory = null , ReadStageInterface $ readStage = null )
46
43
{
47
- $ this ->collectionDataProvider = $ collectionDataProvider ;
48
- $ this ->itemDataProvider = $ itemDataProvider ;
49
- $ this ->subresourceDataProvider = $ subresourceDataProvider ;
50
44
$ this ->serializerContextBuilder = $ serializerContextBuilder ;
51
- $ this ->identifierConverter = $ identifierConverter ;
52
- $ this ->resourceMetadataFactory = $ resourceMetadataFactory ;
45
+ $ this ->readStage = $ readStage ;
46
+ if (null === $ readStage ) {
47
+ @trigger_error (sprintf ('Not injecting "%s" is deprecated since API Platform 2.5 and will not be possible anymore in API Platform 3 ' , ReadStageInterface::class), E_USER_DEPRECATED );
48
+ $ this ->readStage = new ReadStage ($ collectionDataProvider , $ itemDataProvider , $ subresourceDataProvider , $ identifierConverter , $ resourceMetadataFactory );
49
+ }
53
50
}
54
51
55
52
/**
@@ -60,61 +57,33 @@ public function __construct(CollectionDataProviderInterface $collectionDataProvi
60
57
public function onKernelRequest (GetResponseEvent $ event ): void
61
58
{
62
59
$ request = $ event ->getRequest ();
63
- if (
64
- !($ attributes = RequestAttributesExtractor::extractAttributes ($ request ))
65
- || !$ attributes ['receive ' ]
66
- || $ request ->isMethod ('POST ' ) && isset ($ attributes ['collection_operation_name ' ])
67
- || $ this ->isOperationAttributeDisabled ($ attributes , self ::OPERATION_ATTRIBUTE_KEY )
68
- ) {
69
- return ;
70
- }
71
-
72
- if (null === $ filters = $ request ->attributes ->get ('_api_filters ' )) {
60
+ $ attributes = RequestAttributesExtractor::extractAttributes ($ request );
61
+ $ parameters = $ request ->attributes ->all ();
62
+ if (null === $ filters = ($ parameters ['_api_filters ' ] ?? null )) {
73
63
$ queryString = RequestParser::getQueryString ($ request );
74
64
$ filters = $ queryString ? RequestParser::parseRequestParams ($ queryString ) : null ;
75
65
}
76
-
77
- $ context = null === $ filters ? [] : ['filters ' => $ filters ];
66
+ $ normalizationContext = [];
78
67
if ($ this ->serializerContextBuilder ) {
79
- // Builtin data providers are able to use the serialization context to automatically add join clauses
80
- $ context += $ normalizationContext = $ this ->serializerContextBuilder ->createFromRequest ($ request , true , $ attributes );
81
- $ request ->attributes ->set ('_api_normalization_context ' , $ normalizationContext );
82
- }
83
-
84
- if (isset ($ attributes ['collection_operation_name ' ])) {
85
- $ request ->attributes ->set ('data ' , $ this ->getCollectionData ($ attributes , $ context ));
86
-
87
- return ;
88
- }
89
-
90
- $ data = [];
91
-
92
- if ($ this ->identifierConverter ) {
93
- $ context [IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER ] = true ;
68
+ $ normalizationContext = $ this ->serializerContextBuilder ->createFromRequest ($ request , true , $ attributes );
94
69
}
95
70
96
71
try {
97
- $ identifiers = $ this ->extractIdentifiers ($ request ->attributes ->all (), $ attributes );
98
-
99
- if (isset ($ attributes ['item_operation_name ' ])) {
100
- $ data = $ this ->getItemData ($ identifiers , $ attributes , $ context );
101
- } elseif (isset ($ attributes ['subresource_operation_name ' ])) {
102
- // Legacy
103
- if (null === $ this ->subresourceDataProvider ) {
104
- throw new RuntimeException ('No subresource data provider. ' );
105
- }
106
-
107
- $ data = $ this ->getSubresourceData ($ identifiers , $ attributes , $ context );
108
- }
109
- } catch (InvalidIdentifierException $ e ) {
110
- throw new NotFoundHttpException ('Not found, because of an invalid identifier configuration ' , $ e );
72
+ $ data = $ this ->readStage ->apply ($ attributes , $ parameters , $ filters , $ request ->getMethod (), $ normalizationContext );
73
+ } catch (NotFoundException $ e ) {
74
+ throw new NotFoundHttpException ($ e ->getMessage ());
111
75
}
112
76
113
77
if (null === $ data ) {
114
- throw new NotFoundHttpException ('Not Found ' );
78
+ return ;
79
+ }
80
+
81
+ if ($ normalizationContext ) {
82
+ // Builtin data providers are able to use the serialization context to automatically add join clauses
83
+ $ request ->attributes ->set ('_api_normalization_context ' , $ normalizationContext );
115
84
}
116
85
117
86
$ request ->attributes ->set ('data ' , $ data );
118
- $ request ->attributes ->set ('previous_data ' , \is_object ($ data ) ? clone $ data : $ data );
87
+ $ request ->attributes ->set ('previous_data ' , \is_object ($ data ) && ( new \ ReflectionClass ( \get_class ( $ data )))-> isCloneable () ? clone $ data : $ data );
119
88
}
120
89
}
0 commit comments