Skip to content

Instantly share code, notes, and snippets.

@ismail1432
Last active May 6, 2019 13:47
Show Gist options
  • Save ismail1432/5aaed21a89665424ac416f7d8a3c84ce to your computer and use it in GitHub Desktop.
Save ismail1432/5aaed21a89665424ac416f7d8a3c84ce to your computer and use it in GitHub Desktop.
<?php
class CollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
{
private $managerRegistry;
private $collectionExtensions;
private $requestStack;
private $serializer;
/**
* @param QueryCollectionExtensionInterface[]|ContextAwareQueryCollectionExtensionInterface[] $collectionExtensions
*/
public function __construct(
ManagerRegistry $managerRegistry, /* iterable */ $collectionExtensions = [],
RequestStack $requestStack,
SerializerInterface $serializer
) {
$this->managerRegistry = $managerRegistry;
$this->collectionExtensions = $collectionExtensions;
$this->requestStack = $requestStack;
$this->serializer = $serializer;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return null !== $this->managerRegistry->getManagerForClass($resourceClass);
}
/**
* {@inheritdoc}
*
* @throws RuntimeException
*/
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
{
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
$repository = $manager->getRepository($resourceClass);
if (!method_exists($repository, 'createQueryBuilder')) {
throw new RuntimeException('The repository class must have a "createQueryBuilder" method.');
}
$alias = $this->supportFilter($context) ? $this->generateAlias($this->queryParametersToString()) : 'o';
$queryBuilder = $repository->createQueryBuilder($alias);
$queryNameGenerator = new QueryNameGenerator();
foreach ($this->collectionExtensions as $extension) {
$extension->applyToCollection($queryBuilder, $queryNameGenerator, $resourceClass, $operationName, $context);
if ($extension instanceof QueryResultCollectionExtensionInterface && $extension->supportsResult($resourceClass,
$operationName, $context)) {
return $extension->getResult($queryBuilder, $resourceClass, $operationName, $context);
}
}
return $queryBuilder->getQuery()->getResult();
}
private function supportFilter(array $context = []): bool
{
return isset($context['filters']) || \is_array($context['filters']);
}
/**
* Ensure that the query builder alias should not be in the $queryString.
*/
private function generateAlias(string $queryString): string
{
$alias = 'o'.uniqid();
while (false !== strpos($queryString, $alias)) {
$alias = 'o'.uniqid();
}
return $alias;
}
private function queryParametersToString(): string
{
return $this->serializer->serialize($this->requestStack->getCurrentRequest()->query->all(), 'json');
}
}
App\DataProvider\CollectionDataProvider:
arguments:
$collectionExtensions: !tagged api_platform.doctrine.orm.query_extension.collection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment