Created
September 18, 2018 07:26
-
-
Save philippecarle/d99d71b9be62a69b2eb1cf3690957006 to your computer and use it in GitHub Desktop.
Discriminator Filter for API Platform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace AppBundle\Filter; | |
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter; | |
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; | |
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; | |
use Doctrine\Common\Persistence\ManagerRegistry; | |
use Doctrine\Common\Persistence\ObjectManager; | |
use Doctrine\ORM\Mapping\ClassMetadataInfo; | |
use Doctrine\ORM\QueryBuilder; | |
use Psr\Log\LoggerInterface; | |
class DiscriminatorFilter extends AbstractContextAwareFilter | |
{ | |
const FILTER_RESOURCE_TYPE_PROPERTY = 'resourceType'; | |
/** | |
* @var ResourceMetadataFactoryInterface | |
*/ | |
private $resourceMetadataFactory; | |
public function __construct( | |
ManagerRegistry $managerRegistry, | |
ResourceMetadataFactoryInterface $resourceMetadataFactory, | |
LoggerInterface $logger = null, | |
array $properties = null | |
) { | |
parent::__construct($managerRegistry, null, $logger, $properties); | |
$this->resourceMetadataFactory = $resourceMetadataFactory; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getDescription(string $resourceClass): array | |
{ | |
return [ | |
static::FILTER_RESOURCE_TYPE_PROPERTY => [ | |
'property' => static::FILTER_RESOURCE_TYPE_PROPERTY, | |
'type' => 'string', | |
'required' => false, | |
], | |
]; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null, array $context = []) | |
{ | |
if ($property !== static::FILTER_RESOURCE_TYPE_PROPERTY) { | |
return; | |
} | |
/** @var ObjectManager $manager */ | |
$manager = $this->managerRegistry->getManagerForClass($resourceClass); | |
$classMetadataFactory = $manager->getMetadataFactory(); | |
/** @var ClassMetadataInfo $classMetadata */ | |
$classMetadata = $classMetadataFactory->getMetadataFor($resourceClass); | |
foreach ($classMetadata->discriminatorMap as $discriminator => $entityClass) { | |
$metadata = $this->resourceMetadataFactory->create($entityClass); | |
if ($metadata->getShortName() === $value) { | |
$alias = $queryBuilder->getAllAliases()[0]; | |
$queryBuilder->andWhere($alias.' INSTANCE OF :instance'); | |
$queryBuilder->setParameter('instance', $discriminator); | |
return; | |
} | |
} | |
$queryBuilder->where('1=0'); | |
} | |
} |
I tried this class, i created a service and i call the service in my entity :
/**
* A Contact
*
* @ApiResource(attributes={
* "normalization_context"={"groups"={"contact:read"}},
* "denormalization_context"={"groups"={"contact:write"}},
* "filters"={"custom.search_filter"} // call the Discriminator filter
* })
*
It works for me, i can filter with the DiscriminatorColumn name
Thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've made some little modifications to make it compatible with the latest versions of ApiPlatform: