Skip to content

Commit f980613

Browse files
committed
feat(mongodb): resource metadata collection
1 parent 2c2b1d6 commit f980613

30 files changed

+174
-184
lines changed

src/Core/Bridge/Doctrine/EventListener/PublishMercureUpdatesListener.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,18 @@ public function __construct(ResourceClassResolverInterface $resourceClassResolve
9191
$this->graphQlMercureSubscriptionIriGenerator = $graphQlMercureSubscriptionIriGenerator;
9292
$this->reset();
9393

94-
$rawurlencode = ExpressionFunction::fromPhp('rawurlencode', 'escape');
95-
$this->expressionLanguage->addFunction($rawurlencode);
96-
97-
$this->expressionLanguage->addFunction(
98-
new ExpressionFunction('iri', static function (string $apiResource, int $referenceType = UrlGeneratorInterface::ABS_URL): string {
99-
return sprintf('iri(%s, %d)', $apiResource, $referenceType);
100-
}, static function (array $arguments, $apiResource, int $referenceType = UrlGeneratorInterface::ABS_URL) use ($iriConverter): string {
101-
return $iriConverter->getIriFromItem($apiResource, null, $referenceType);
102-
})
103-
);
94+
if ($this->expressionLanguage) {
95+
$rawurlencode = ExpressionFunction::fromPhp('rawurlencode', 'escape');
96+
$this->expressionLanguage->addFunction($rawurlencode);
97+
98+
$this->expressionLanguage->addFunction(
99+
new ExpressionFunction('iri', static function (string $apiResource, int $referenceType = UrlGeneratorInterface::ABS_URL): string {
100+
return sprintf('iri(%s, %d)', $apiResource, $referenceType);
101+
}, static function (array $arguments, $apiResource, int $referenceType = UrlGeneratorInterface::ABS_URL) use ($iriConverter): string {
102+
return $iriConverter->getIriFromItem($apiResource, null, $referenceType);
103+
})
104+
);
105+
}
104106
}
105107

106108
/**

src/Core/Bridge/Doctrine/MongoDbOdm/CollectionDataProvider.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
1919
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
2020
use ApiPlatform\Core\Exception\RuntimeException;
21-
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
22-
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2321
use Doctrine\ODM\MongoDB\DocumentManager;
2422
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
2523
use Doctrine\Persistence\ManagerRegistry;
@@ -43,11 +41,6 @@ final class CollectionDataProvider implements CollectionDataProviderInterface, R
4341
public function __construct(ManagerRegistry $managerRegistry, $resourceMetadataFactory, iterable $collectionExtensions = [])
4442
{
4543
$this->managerRegistry = $managerRegistry;
46-
47-
if (!$resourceMetadataFactory instanceof ResourceMetadataCollectionFactoryInterface) {
48-
trigger_deprecation('api-platform/core', '2.7', sprintf('Use "%s" instead of "%s".', ResourceMetadataCollectionFactoryInterface::class, ResourceMetadataFactoryInterface::class));
49-
}
50-
5144
$this->resourceMetadataFactory = $resourceMetadataFactory;
5245
$this->collectionExtensions = $collectionExtensions;
5346
}
@@ -81,7 +74,7 @@ public function getCollection(string $resourceClass, string $operationName = nul
8174
}
8275
}
8376

84-
$attribute = $this->resourceMetadataFactory->create($resourceClass)->getOperation($operationName)->getExtraProperties();
77+
$attribute = $this->resourceMetadataFactory->create($resourceClass)->getOperation($operationName)->getExtraProperties()['doctrine_mongodb'] ?? [];
8578
$executeOptions = $attribute['execute_options'] ?? [];
8679

8780
return $aggregationBuilder->hydrate($resourceClass)->execute($executeOptions);

src/Core/Bridge/Doctrine/MongoDbOdm/Extension/OrderExtension.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ final class OrderExtension implements AggregationCollectionExtensionInterface
4141

4242
public function __construct(string $order = null, $resourceMetadataFactory = null, ManagerRegistry $managerRegistry = null)
4343
{
44-
if (!$resourceMetadataFactory instanceof ResourceMetadataCollectionFactoryInterface) {
44+
if ($resourceMetadataFactory && !$resourceMetadataFactory instanceof ResourceMetadataCollectionFactoryInterface) {
4545
trigger_deprecation('api-platform/core', '2.7', sprintf('Use "%s" instead of "%s".', ResourceMetadataCollectionFactoryInterface::class, ResourceMetadataFactoryInterface::class));
4646
}
4747

@@ -58,10 +58,13 @@ public function applyToCollection(Builder $aggregationBuilder, string $resourceC
5858
$classMetaData = $this->getClassMetadata($resourceClass);
5959
$identifiers = $classMetaData->getIdentifier();
6060
if (null !== $this->resourceMetadataFactory) {
61-
$defaultOrder = $this->resourceMetadataFactory->create($resourceClass)->getOperation($operationName)->getOrders();
62-
if (empty($defaultOrder)) {
61+
if ($this->resourceMetadataFactory instanceof ResourceMetadataCollectionFactoryInterface) {
62+
$metadata = $this->resourceMetadataFactory->create($resourceClass);
63+
$defaultOrder = isset($context['graphql_operation_name']) ? $metadata->getGraphQlOperation($operationName)->getOrder() : $metadata->getOperation($operationName)->getOrder();
64+
} else {
6365
$defaultOrder = $this->resourceMetadataFactory->create($resourceClass)->getAttribute('order');
6466
}
67+
6568
if (null !== $defaultOrder) {
6669
foreach ($defaultOrder as $field => $order) {
6770
if (\is_int($field)) {

src/Core/Bridge/Doctrine/MongoDbOdm/Extension/PaginationExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public function getResult(Builder $aggregationBuilder, string $resourceClass, st
122122
throw new RuntimeException(sprintf('The manager for "%s" must be an instance of "%s".', $resourceClass, DocumentManager::class));
123123
}
124124

125-
$attribute = $this->resourceMetadataFactory->create($resourceClass)->getOperation($operationName)->getExtraProperties();
125+
$attribute = $this->resourceMetadataFactory->create($resourceClass)->getOperation($operationName)->getExtraProperties()['doctrine_mongodb'] ?? [];
126126
$executeOptions = $attribute['execute_options'] ?? [];
127127

128128
return new Paginator($aggregationBuilder->execute($executeOptions), $manager->getUnitOfWork(), $resourceClass, $aggregationBuilder->getPipeline());

src/Core/Bridge/Doctrine/MongoDbOdm/ItemDataProvider.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2525
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
2626
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
27+
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2728
use Doctrine\ODM\MongoDB\DocumentManager;
2829
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
2930
use Doctrine\Persistence\ManagerRegistry;
@@ -105,7 +106,13 @@ public function getItem(string $resourceClass, $id, string $operationName = null
105106
}
106107

107108
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
108-
$attribute = $resourceMetadata->getItemOperationAttribute($operationName, 'doctrine_mongodb', [], true);
109+
110+
if ($resourceMetadata instanceof ResourceMetadataCollection) {
111+
$attribute = $resourceMetadata->getOperation($operationName)->getExtraProperties()['doctrine_mongodb'] ?? [];
112+
} else {
113+
$attribute = $resourceMetadata->getItemOperationAttribute($operationName, 'doctrine_mongodb', [], true);
114+
}
115+
109116
$executeOptions = $attribute['execute_options'] ?? [];
110117

111118
return $aggregationBuilder->hydrate($resourceClass)->execute($executeOptions)->current() ?: null;

src/Core/Bridge/Doctrine/MongoDbOdm/PropertyInfo/DoctrineExtractor.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,13 @@ public function getTypes($class, $property, array $context = [])
6363
}
6464

6565
if ($metadata->hasAssociation($property)) {
66+
/** @var class-string|null */
6667
$class = $metadata->getAssociationTargetClass($property);
6768

69+
if (null === $class) {
70+
return null;
71+
}
72+
6873
if ($metadata->isSingleValuedAssociation($property)) {
6974
$nullable = $metadata instanceof MongoDbClassMetadata && $metadata->isNullable($property);
7075

src/Core/Bridge/Doctrine/MongoDbOdm/SubresourceDataProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public function getSubresource(string $resourceClass, array $identifiers, array
8989
throw new ResourceClassNotSupportedException('The given resource class is not a subresource.');
9090
}
9191

92-
$attribute = $this->resourceMetadataFactory->create($resourceClass)->getOperation($operationName)->getExtraProperties();
92+
$attribute = $this->resourceMetadataFactory->create($resourceClass)->getOperation($operationName)->getExtraProperties()['doctrine_mongodb'] ?? [];
9393
$executeOptions = $attribute['execute_options'] ?? [];
9494

9595
$aggregationBuilder = $this->buildAggregation($identifiers, $context, $executeOptions, $repository->createAggregationBuilder(), \count($context['identifiers']));

tests/Core/Bridge/Doctrine/MongoDbOdm/CollectionDataProviderTest.php renamed to tests/Bridge/Doctrine/MongoDbOdm/CollectionDataProviderTest.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationCollectionExtensionInterface;
1818
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationResultCollectionExtensionInterface;
1919
use ApiPlatform\Core\Exception\RuntimeException;
20-
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
21-
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
2220
use ApiPlatform\Core\Tests\ProphecyTrait;
21+
use ApiPlatform\Metadata\ApiResource;
22+
use ApiPlatform\Metadata\GetCollection;
23+
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
24+
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2325
use ApiPlatform\Tests\Fixtures\TestBundle\Document\Dummy;
2426
use Doctrine\ODM\MongoDB\Aggregation\Builder;
2527
use Doctrine\ODM\MongoDB\DocumentManager;
@@ -33,7 +35,6 @@
3335
* @author Alan Poulain <contact@alanpoulain.eu>
3436
*
3537
* @group mongodb
36-
* @group legacy
3738
*/
3839
class CollectionDataProviderTest extends TestCase
3940
{
@@ -50,7 +51,7 @@ protected function setUp(): void
5051
parent::setUp();
5152

5253
$this->managerRegistryProphecy = $this->prophesize(ManagerRegistry::class);
53-
$this->resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
54+
$this->resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
5455
}
5556

5657
public function testGetCollection()
@@ -70,7 +71,7 @@ public function testGetCollection()
7071

7172
$this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled();
7273

73-
$this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata());
74+
$this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [(new ApiResource())->withOperations(['foo' => new GetCollection()])]));
7475

7576
$extensionProphecy = $this->prophesize(AggregationCollectionExtensionInterface::class);
7677
$extensionProphecy->applyToCollection($aggregationBuilder, Dummy::class, 'foo', [])->shouldBeCalled();
@@ -96,13 +97,7 @@ public function testGetCollectionWithExecuteOptions()
9697

9798
$this->managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled();
9899

99-
$this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata(
100-
'Dummy',
101-
null,
102-
null,
103-
null,
104-
['foo' => ['doctrine_mongodb' => ['execute_options' => ['allowDiskUse' => true]]]]
105-
));
100+
$this->resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [(new ApiResource())->withOperations(['foo' => (new GetCollection())->withExtraProperties(['doctrine_mongodb' => ['execute_options' => ['allowDiskUse' => true]]])])]));
106101

107102
$extensionProphecy = $this->prophesize(AggregationCollectionExtensionInterface::class);
108103
$extensionProphecy->applyToCollection($aggregationBuilder, Dummy::class, 'foo', [])->shouldBeCalled();

tests/Core/Bridge/Doctrine/MongoDbOdm/Extension/FilterExtensionTest.php renamed to tests/Bridge/Doctrine/MongoDbOdm/Extension/FilterExtensionTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
use ApiPlatform\Core\Api\FilterInterface as ApiFilterInterface;
1717
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\FilterExtension;
1818
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Filter\FilterInterface;
19-
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
20-
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
2119
use ApiPlatform\Core\Tests\ProphecyTrait;
20+
use ApiPlatform\Metadata\ApiResource;
21+
use ApiPlatform\Metadata\GetCollection;
22+
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
23+
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2224
use ApiPlatform\Tests\Fixtures\TestBundle\Document\Dummy;
2325
use Doctrine\ODM\MongoDB\Aggregation\Builder;
2426
use PHPUnit\Framework\TestCase;
@@ -28,7 +30,6 @@
2830
* @author Alan Poulain <contact@alanpoulain.eu>
2931
*
3032
* @group mongodb
31-
* @group legacy
3233
*/
3334
class FilterExtensionTest extends TestCase
3435
{
@@ -38,8 +39,8 @@ public function testApplyToCollectionWithValidFilters()
3839
{
3940
$aggregationBuilderProphecy = $this->prophesize(Builder::class);
4041

41-
$dummyMetadata = new ResourceMetadata('dummy', 'dummy', '#dummy', ['get' => ['method' => 'GET'], 'put' => ['method' => 'PUT']], ['get' => ['method' => 'GET', 'filters' => ['dummyFilter', 'dummyBadFilter']], 'post' => ['method' => 'POST'], 'custom' => ['method' => 'GET', 'path' => '/foo'], 'custom2' => ['method' => 'POST', 'path' => '/foo']], []);
42-
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
42+
$dummyMetadata = new ResourceMetadataCollection(Dummy::class, [(new ApiResource())->withOperations(['get' => (new GetCollection())->withFilters(['dummyFilter', 'dummyBadFilter'])])]);
43+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
4344
$resourceMetadataFactoryProphecy->create(Dummy::class)->shouldBeCalled()->willReturn($dummyMetadata);
4445

4546
$aggregationBuilder = $aggregationBuilderProphecy->reveal();
@@ -61,9 +62,8 @@ public function testApplyToCollectionWithValidFilters()
6162

6263
public function testApplyToCollectionWithoutFilters()
6364
{
64-
$dummyMetadata = new ResourceMetadata('dummy', 'dummy', '#dummy', ['get' => ['method' => 'GET'], 'put' => ['method' => 'PUT']], ['get' => ['method' => 'GET'], 'post' => ['method' => 'POST'], 'custom' => ['method' => 'GET', 'path' => '/foo'], 'custom2' => ['method' => 'POST', 'path' => '/foo']]);
65-
66-
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
65+
$dummyMetadata = new ResourceMetadataCollection(Dummy::class, [(new ApiResource())->withOperations(['get' => (new GetCollection())->withFilters(['dummyFilter', 'dummyBadFilter'])])]);
66+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
6767
$resourceMetadataFactoryProphecy->create(Dummy::class)->shouldBeCalled()->willReturn($dummyMetadata);
6868

6969
$orderExtensionTest = new FilterExtension($resourceMetadataFactoryProphecy->reveal(), $this->prophesize(ContainerInterface::class)->reveal());

0 commit comments

Comments
 (0)