1919use ApiPlatform \Core \Api \OperationType ;
2020use ApiPlatform \Core \Api \UrlGeneratorInterface ;
2121use ApiPlatform \Core \DataProvider \ItemDataProviderInterface ;
22+ use ApiPlatform \Core \DataProvider \OperationDataProviderTrait ;
23+ use ApiPlatform \Core \DataProvider \SubresourceDataProviderInterface ;
2224use ApiPlatform \Core \Exception \InvalidArgumentException ;
25+ use ApiPlatform \Core \Exception \InvalidIdentifierException ;
2326use ApiPlatform \Core \Exception \ItemNotFoundException ;
2427use ApiPlatform \Core \Exception \RuntimeException ;
2528use ApiPlatform \Core \Identifier \Normalizer \ChainIdentifierDenormalizer ;
2629use ApiPlatform \Core \Metadata \Property \Factory \PropertyMetadataFactoryInterface ;
2730use ApiPlatform \Core \Metadata \Property \Factory \PropertyNameCollectionFactoryInterface ;
31+ use ApiPlatform \Core \Util \AttributesExtractor ;
2832use ApiPlatform \Core \Util \ClassInfoTrait ;
2933use Symfony \Component \PropertyAccess \PropertyAccess ;
3034use Symfony \Component \PropertyAccess \PropertyAccessorInterface ;
3943final class IriConverter implements IriConverterInterface
4044{
4145 use ClassInfoTrait;
46+ use OperationDataProviderTrait;
4247
43- private $ itemDataProvider ;
4448 private $ routeNameResolver ;
4549 private $ router ;
4650 private $ identifiersExtractor ;
47- private $ identifierDenormalizer ;
4851
49- public function __construct (PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory , PropertyMetadataFactoryInterface $ propertyMetadataFactory , ItemDataProviderInterface $ itemDataProvider , RouteNameResolverInterface $ routeNameResolver , RouterInterface $ router , PropertyAccessorInterface $ propertyAccessor = null , IdentifiersExtractorInterface $ identifiersExtractor = null , ChainIdentifierDenormalizer $ identifierDenormalizer = null )
52+ public function __construct (PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory , PropertyMetadataFactoryInterface $ propertyMetadataFactory , ItemDataProviderInterface $ itemDataProvider , RouteNameResolverInterface $ routeNameResolver , RouterInterface $ router , PropertyAccessorInterface $ propertyAccessor = null , IdentifiersExtractorInterface $ identifiersExtractor = null , ChainIdentifierDenormalizer $ identifierDenormalizer = null , SubresourceDataProviderInterface $ subresourceDataProvider = null )
5053 {
5154 $ this ->itemDataProvider = $ itemDataProvider ;
5255 $ this ->routeNameResolver = $ routeNameResolver ;
5356 $ this ->router = $ router ;
57+ $ this ->identifiersExtractor = $ identifiersExtractor ;
5458 $ this ->identifierDenormalizer = $ identifierDenormalizer ;
59+ $ this ->subresourceDataProvider = $ subresourceDataProvider ;
5560
5661 if (null === $ identifiersExtractor ) {
57- @trigger_error ('Not injecting ItemIdentifiersExtractor is deprecated since API Platform 2.1 and will not be possible anymore in API Platform 3 ' , E_USER_DEPRECATED );
62+ @trigger_error (sprintf ( 'Not injecting "%s" is deprecated since API Platform 2.1 and will not be possible anymore in API Platform 3 ' , IdentifiersExtractorInterface::class) , E_USER_DEPRECATED );
5863 $ this ->identifiersExtractor = new IdentifiersExtractor ($ propertyNameCollectionFactory , $ propertyMetadataFactory , $ propertyAccessor ?? PropertyAccess::createPropertyAccessor ());
59- } else {
60- $ this ->identifiersExtractor = $ identifiersExtractor ;
61- }
62-
63- if (null === $ identifierDenormalizer ) {
64- @trigger_error (sprintf ('Not injecting "%s" is deprecated since API Platform 2.2 and will not be possible anymore in API Platform 3. ' , ChainIdentifierDenormalizer::class), E_USER_DEPRECATED );
6564 }
6665 }
6766
@@ -76,18 +75,31 @@ public function getItemFromIri(string $iri, array $context = [])
7675 throw new InvalidArgumentException (sprintf ('No route matches "%s". ' , $ iri ), $ e ->getCode (), $ e );
7776 }
7877
79- if (!isset ($ parameters ['_api_resource_class ' ], $ parameters [ ' id ' ] )) {
78+ if (!isset ($ parameters ['_api_resource_class ' ])) {
8079 throw new InvalidArgumentException (sprintf ('No resource associated to "%s". ' , $ iri ));
8180 }
8281
83- $ identifiers = $ parameters ['id ' ];
82+ $ attributes = AttributesExtractor::extractAttributes ($ parameters );
83+
84+ try {
85+ $ identifiers = $ this ->extractIdentifiers ($ parameters , $ attributes );
86+ } catch (InvalidIdentifierException $ e ) {
87+ throw new InvalidArgumentException ($ e ->getMessage (), $ e ->getCode (), $ e );
88+ }
8489
8590 if ($ this ->identifierDenormalizer ) {
86- $ identifiers = $ this ->identifierDenormalizer ->denormalize ((string ) $ parameters ['id ' ], $ parameters ['_api_resource_class ' ]);
8791 $ context [ChainIdentifierDenormalizer::HAS_IDENTIFIER_DENORMALIZER ] = true ;
8892 }
8993
90- if ($ item = $ this ->itemDataProvider ->getItem ($ parameters ['_api_resource_class ' ], $ identifiers , $ parameters ['_api_item_operation_name ' ] ?? null , $ context )) {
94+ if (isset ($ attributes ['subresource_operation_name ' ])) {
95+ if ($ item = $ this ->getSubresourceData ($ identifiers , $ attributes , $ context )) {
96+ return $ item ;
97+ }
98+
99+ throw new ItemNotFoundException (sprintf ('Item not found for "%s". ' , $ iri ));
100+ }
101+
102+ if ($ item = $ this ->getItemData ($ identifiers , $ attributes , $ context )) {
91103 return $ item ;
92104 }
93105
0 commit comments