Skip to content

Commit

Permalink
Merge 48f8318 into 5df77ad
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Feb 6, 2021
2 parents 5df77ad + 48f8318 commit 246e303
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
7 changes: 6 additions & 1 deletion src/DataProvider/OperationDataProviderTrait.php
Expand Up @@ -16,6 +16,7 @@
use ApiPlatform\Core\Exception\InvalidIdentifierException;
use ApiPlatform\Core\Exception\RuntimeException;
use ApiPlatform\Core\Identifier\CompositeIdentifierParser;
use ApiPlatform\Core\Identifier\ContextAwareIdentifierConverterInterface;
use ApiPlatform\Core\Identifier\IdentifierConverterInterface;

/**
Expand Down Expand Up @@ -106,7 +107,7 @@ private function extractIdentifiers(array $parameters, array $attributes)
throw new InvalidIdentifierException(sprintf('Expected %d identifiers, got %d', $identifiersNumber, $currentIdentifiersNumber));
}

return $this->identifierConverter->convert($identifiers, $attributes['resource_class']);
return $this->identifierConverter->convert($identifiers, $identifiedBy[0]);
}

// TODO: Subresources tuple may have a third item representing if it is a "collection", this behavior will be removed in 3.0
Expand All @@ -120,6 +121,10 @@ private function extractIdentifiers(array $parameters, array $attributes)
$identifiers[$parameterName] = $parameters[$parameterName];
}

if ($this->identifierConverter instanceof ContextAwareIdentifierConverterInterface) {
return $this->identifierConverter->convert($identifiers, $attributes['resource_class'], ['identifiers' => $identifiersKeys]);
}

return $this->identifierConverter->convert($identifiers, $attributes['resource_class']);
}
}
9 changes: 5 additions & 4 deletions src/Identifier/IdentifierConverter.php
Expand Up @@ -56,8 +56,9 @@ public function convert($data, string $class, array $context = []): array
}

$identifiers = $data;
foreach ($data as $identifier => $value) {
if (null === $type = $this->getIdentifierType($class, $identifier)) {

foreach ($data as $parameter => $value) {
if (null === $type = $this->getIdentifierType($context['identifiers'][$parameter][0] ?? $class, $context['identifiers'][$parameter][1] ?? $parameter)) {
continue;
}

Expand All @@ -68,10 +69,10 @@ public function convert($data, string $class, array $context = []): array
}

try {
$identifiers[$identifier] = $identifierTransformer->denormalize($value, $type);
$identifiers[$parameter] = $identifierTransformer->denormalize($value, $type);
break;
} catch (InvalidIdentifierException $e) {
throw new InvalidIdentifierException(sprintf('Identifier "%s" could not be denormalized.', $identifier), $e->getCode(), $e);
throw new InvalidIdentifierException(sprintf('Identifier "%s" could not be denormalized.', $parameter), $e->getCode(), $e);
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions tests/Identifier/IdentifierConverterTest.php
Expand Up @@ -121,4 +121,27 @@ public function testShouldBreakAfterTransforming()

$this->assertSame(['id' => 42], $identifierDenormalizer->convert($identifier, $class));
}

public function testWithContextAndMultipleIdentifiers()
{
$identifier = ['id' => '42', 'book' => '21'];

$integerIdentifierPropertyMetadata = (new PropertyMetadata())->withIdentifier(true)->withType(new Type(Type::BUILTIN_TYPE_INT));

$propertyMetadataFactory = $this->prophesize(PropertyMetadataFactoryInterface::class);
$propertyMetadataFactory->create('Author', 'id')->shouldBeCalled()->willReturn($integerIdentifierPropertyMetadata);
$propertyMetadataFactory->create('Book', 'id')->shouldBeCalled()->willReturn($integerIdentifierPropertyMetadata);

$identifiersExtractor = $this->prophesize(IdentifiersExtractorInterface::class);
$identifiersExtractor->getIdentifiersFromResourceClass('Book')->willReturn(['id']);
$identifiersExtractor->getIdentifiersFromResourceClass('Author')->willReturn(['id']);

$shouldNotBeCalled = $this->prophesize(DenormalizerInterface::class);
$shouldNotBeCalled->supportsDenormalization()->shouldNotBeCalled();

$identifierDenormalizers = [new IntegerDenormalizer(), $shouldNotBeCalled->reveal()];
$identifierDenormalizer = new IdentifierConverter($identifiersExtractor->reveal(), $propertyMetadataFactory->reveal(), $identifierDenormalizers);

$this->assertSame(['id' => 42, 'book' => 21], $identifierDenormalizer->convert($identifier, 'Book', ['identifiers' => ['id' => ['Author', 'id'], 'book' => ['Book', 'id']]]));
}
}

0 comments on commit 246e303

Please sign in to comment.