| 
 | 1 | +<?php  | 
 | 2 | + | 
 | 3 | +namespace App\Doctrine\Filter;  | 
 | 4 | + | 
 | 5 | +use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;  | 
 | 6 | +use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;  | 
 | 7 | +use ApiPlatform\Metadata\IriConverterInterface;  | 
 | 8 | +use ApiPlatform\Metadata\Operation;  | 
 | 9 | +use App\Entity\BelongsToCampInterface;  | 
 | 10 | +use App\Entity\Camp;  | 
 | 11 | +use App\Entity\CampCollaboration;  | 
 | 12 | +use App\Util\QueryBuilderHelper;  | 
 | 13 | +use Doctrine\ORM\QueryBuilder;  | 
 | 14 | +use Doctrine\Persistence\ManagerRegistry;  | 
 | 15 | +use Psr\Log\LoggerInterface;  | 
 | 16 | +use Symfony\Component\PropertyInfo\Type;  | 
 | 17 | +use Symfony\Component\Serializer\NameConverter\NameConverterInterface;  | 
 | 18 | + | 
 | 19 | +final class CampCollaboratorFilter extends AbstractFilter {  | 
 | 20 | +    public const QUERY_PARAM_NAME = 'campCollaborator';  | 
 | 21 | + | 
 | 22 | +    public function __construct(  | 
 | 23 | +        private IriConverterInterface $iriConverter,  | 
 | 24 | +        private QueryBuilderHelper $queryBuilderHelper,  | 
 | 25 | +        ManagerRegistry $managerRegistry,  | 
 | 26 | +        ?LoggerInterface $logger = null,  | 
 | 27 | +        ?array $properties = null,  | 
 | 28 | +        ?NameConverterInterface $nameConverter = null  | 
 | 29 | +    ) {  | 
 | 30 | +        parent::__construct($managerRegistry, $logger, $properties, $nameConverter);  | 
 | 31 | +    }  | 
 | 32 | + | 
 | 33 | +    // This function is only used to hook in documentation generators (supported by Swagger and Hydra)  | 
 | 34 | +    public function getDescription(string $resourceClass): array {  | 
 | 35 | +        return [self::QUERY_PARAM_NAME => [  | 
 | 36 | +            'property' => self::QUERY_PARAM_NAME,  | 
 | 37 | +            'type' => Type::BUILTIN_TYPE_STRING,  | 
 | 38 | +            'required' => false,  | 
 | 39 | +        ]];  | 
 | 40 | +    }  | 
 | 41 | + | 
 | 42 | +    protected function filterProperty(  | 
 | 43 | +        string $property,  | 
 | 44 | +        $value,  | 
 | 45 | +        QueryBuilder $queryBuilder,  | 
 | 46 | +        QueryNameGeneratorInterface $queryNameGenerator,  | 
 | 47 | +        string $resourceClass,  | 
 | 48 | +        ?Operation $operation = null,  | 
 | 49 | +        array $context = []  | 
 | 50 | +    ): void {  | 
 | 51 | +        if (!class_implements($resourceClass, BelongsToCampInterface::class)) {  | 
 | 52 | +            throw new \Exception("CampCollaboratorFilter can only be applied to entities which implement BelongsToCampInterface (received: {$resourceClass}).");  | 
 | 53 | +        }  | 
 | 54 | + | 
 | 55 | +        if (self::QUERY_PARAM_NAME !== $property) {  | 
 | 56 | +            return;  | 
 | 57 | +        }  | 
 | 58 | + | 
 | 59 | +        $campAlias = Camp::class === $resourceClass ?  | 
 | 60 | +            $queryBuilder->getRootAliases()[0] :  | 
 | 61 | +            $this->queryBuilderHelper->findOrAddInnerRootJoinAlias($queryBuilder, $queryNameGenerator, 'camp');  | 
 | 62 | + | 
 | 63 | +        // load user from query parameter value  | 
 | 64 | +        $collaborator = $this->iriConverter->getResourceFromIri($value);  | 
 | 65 | + | 
 | 66 | +        $campsQry = $queryBuilder->getEntityManager()->createQueryBuilder();  | 
 | 67 | +        $campsQry->select('identity(cc.camp)');  | 
 | 68 | +        $campsQry->from(CampCollaboration::class, 'cc');  | 
 | 69 | +        $campsQry->andWhere('cc.user = :collaborator');  | 
 | 70 | +        $campsQry->andWhere('cc.status = :status_established');  | 
 | 71 | + | 
 | 72 | +        $queryBuilder->andWhere($queryBuilder->expr()->in($campAlias, $campsQry->getDQL()));  | 
 | 73 | +        $queryBuilder->setParameter('collaborator', $collaborator);  | 
 | 74 | +        $queryBuilder->setParameter('status_established', CampCollaboration::STATUS_ESTABLISHED);  | 
 | 75 | +    }  | 
 | 76 | +}  | 
0 commit comments