Allow to filter users by email, name or username

This commit is contained in:
2024-04-18 14:33:08 +02:00
parent fd025a22ea
commit c71fbdf8ef
2 changed files with 66 additions and 5 deletions
+2 -5
View File
@@ -2,9 +2,9 @@
namespace App\Entity;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata as API;
use App\Entity\Interface\UserOwnedInterface;
use App\Filter\UserQueryFilter;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
@@ -29,10 +29,7 @@ use Symfony\Component\Validator\Constraints as Assert;
#[API\Put(security: 'is_granted("USER_EDIT", object)')]
#[API\Delete(security: 'is_granted("USER_EDIT", object)')]
#[API\Patch(security: 'is_granted("USER_EDIT", object)')]
#[API\ApiFilter(filterClass: SearchFilter::class, properties: [
'username' => 'partial',
'name' => 'partial'
])]
#[API\ApiFilter(filterClass: UserQueryFilter::class, properties: ['query'])]
#[UniqueEntity(fields: ['username'], message: 'This usernames already exists.')]
#[UniqueEntity(fields: ['email'], message: 'This email address is already registered.')]
#[ORM\Entity(repositoryClass: UserRepository::class)]
+64
View File
@@ -0,0 +1,64 @@
<?php
namespace App\Filter;
use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Psr\Log\LoggerInterface;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
final class UserQueryFilter extends AbstractFilter
{
public function __construct(
protected ManagerRegistry $managerRegistry,
?LoggerInterface $logger = null,
protected ?array $properties = null,
protected ?NameConverterInterface $nameConverter = null
) {
parent::__construct($managerRegistry, $logger, $properties, $nameConverter);
}
protected function filterProperty(
string $property,
$value,
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,
Operation $operation = null,
array $context = []
): void {
if (
!$this->isPropertyEnabled($property, $resourceClass)
) {
return;
}
$rootAlias = $queryBuilder->getRootAliases()[0];
$parameterName = $queryNameGenerator->generateParameterName($property);
$queryBuilder
->andWhere(sprintf('%s.email LIKE :%s', $rootAlias, $parameterName))
->orWhere(sprintf('%s.name LIKE :%s', $rootAlias, $parameterName))
->orWhere(sprintf('%s.username LIKE :%s', $rootAlias, $parameterName))
->setParameter($parameterName, $value);
}
public function getDescription(string $resourceClass): array
{
$description = [];
foreach ($this->properties as $property => $strategy) {
$description["$property"] = [
'property' => $property,
'type' => Type::BUILTIN_TYPE_STRING,
'required' => false,
'description' => 'Query Users by email, name or username. Fuzzy.',
];
}
return $description;
}
}