-
-
Notifications
You must be signed in to change notification settings - Fork 928
feat(doctrine): stateOptions can handleLinks for query optimization #5732
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Feature: Use a link handler to retrieve a resource | ||
|
||
@createSchema | ||
Scenario: Get collection | ||
Given there are a few link handled dummies | ||
When I send a "GET" request to "/link_handled_dummies" | ||
Then the response status code should be 200 | ||
And the response should be in JSON | ||
And the JSON node "hydra:totalItems" should be equal to 1 | ||
|
||
@createSchema | ||
Scenario: Get item | ||
Given there are a few link handled dummies | ||
When I send a "GET" request to "/link_handled_dummies/1" | ||
Then the response status code should be 200 | ||
And the response should be in JSON | ||
And the JSON node "slug" should be equal to "foo" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ | |
use Doctrine\ODM\MongoDB\DocumentManager; | ||
use Doctrine\ODM\MongoDB\Repository\DocumentRepository; | ||
use Doctrine\Persistence\ManagerRegistry; | ||
use Psr\Container\ContainerInterface; | ||
|
||
/** | ||
* Collection state provider using the Doctrine ODM. | ||
|
@@ -33,37 +34,46 @@ final class CollectionProvider implements ProviderInterface | |
/** | ||
* @param AggregationCollectionExtensionInterface[] $collectionExtensions | ||
*/ | ||
public function __construct(ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly ManagerRegistry $managerRegistry, private readonly iterable $collectionExtensions = []) | ||
public function __construct(ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly ManagerRegistry $managerRegistry, private readonly iterable $collectionExtensions = [], ContainerInterface $handleLinksLocator = null) | ||
{ | ||
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory; | ||
$this->handleLinksLocator = $handleLinksLocator; | ||
} | ||
|
||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): iterable | ||
{ | ||
$resourceClass = $operation->getClass(); | ||
$documentClass = $operation->getClass(); | ||
if (($options = $operation->getStateOptions()) && $options instanceof Options && $options->getDocumentClass()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redundant with Can't it be in a more generic trait (e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a quite hard problem I'm not a huge fan of the current dependency between CollectionFiltersNormalizer and state options as when we'll need to subtree split we potentially won't have access to them. When working on this we probably need to uplift this information into some Magic is hard to implement correctly :|. |
||
$documentClass = $options->getDocumentClass(); | ||
} | ||
|
||
/** @var DocumentManager $manager */ | ||
$manager = $this->managerRegistry->getManagerForClass($resourceClass); | ||
$manager = $this->managerRegistry->getManagerForClass($documentClass); | ||
|
||
$repository = $manager->getRepository($resourceClass); | ||
$repository = $manager->getRepository($documentClass); | ||
if (!$repository instanceof DocumentRepository) { | ||
throw new RuntimeException(sprintf('The repository for "%s" must be an instance of "%s".', $resourceClass, DocumentRepository::class)); | ||
throw new RuntimeException(sprintf('The repository for "%s" must be an instance of "%s".', $documentClass, DocumentRepository::class)); | ||
} | ||
|
||
$aggregationBuilder = $repository->createAggregationBuilder(); | ||
|
||
$this->handleLinks($aggregationBuilder, $uriVariables, $context, $resourceClass, $operation); | ||
if ($handleLinks = $this->getLinksHandler($operation)) { | ||
$handleLinks($aggregationBuilder, $uriVariables, ['documentClass' => $documentClass, 'operation' => $operation] + $context); | ||
} else { | ||
$this->handleLinks($aggregationBuilder, $uriVariables, $context, $documentClass, $operation); | ||
} | ||
|
||
foreach ($this->collectionExtensions as $extension) { | ||
$extension->applyToCollection($aggregationBuilder, $resourceClass, $operation, $context); | ||
$extension->applyToCollection($aggregationBuilder, $documentClass, $operation, $context); | ||
|
||
if ($extension instanceof AggregationResultCollectionExtensionInterface && $extension->supportsResult($resourceClass, $operation, $context)) { | ||
return $extension->getResult($aggregationBuilder, $resourceClass, $operation, $context); | ||
if ($extension instanceof AggregationResultCollectionExtensionInterface && $extension->supportsResult($documentClass, $operation, $context)) { | ||
return $extension->getResult($aggregationBuilder, $documentClass, $operation, $context); | ||
} | ||
} | ||
|
||
$attribute = $operation->getExtraProperties()['doctrine_mongodb'] ?? []; | ||
$executeOptions = $attribute['execute_options'] ?? []; | ||
|
||
return $aggregationBuilder->hydrate($resourceClass)->execute($executeOptions); | ||
return $aggregationBuilder->hydrate($documentClass)->execute($executeOptions); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.