From ecd8be50cf9b7b7568589f138b47c7d5f8ae5bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Zapletal?= Date: Sun, 28 Jul 2024 18:23:47 +0200 Subject: [PATCH] Fixed searchables for Postgres DB --- .../SearchBuilder/SearchBuilder.php | 29 +++++++++++++++---- src/Collection/SearchBuilder/Searchable.php | 21 ++++++++++++-- src/Recipe/AdminRecipe.php | 8 +++-- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/Collection/SearchBuilder/SearchBuilder.php b/src/Collection/SearchBuilder/SearchBuilder.php index f7aba6f..293e20e 100644 --- a/src/Collection/SearchBuilder/SearchBuilder.php +++ b/src/Collection/SearchBuilder/SearchBuilder.php @@ -5,6 +5,7 @@ use Doctrine\ORM\QueryBuilder; use Megio\Collection\CollectionRequest; +use Symfony\Component\Uid\UuidV6; class SearchBuilder { @@ -33,7 +34,9 @@ public function build(): QueryBuilder if ($searchText !== null) { $whereDql = []; - foreach ($this->searchables as $searchable) { + $validSearchables = array_filter($this->searchables, fn(Searchable $searchable) => $searchable->isEnabled($searchText)); + + foreach ($validSearchables as $searchable) { $relationCol = $searchable->getRelation(); $colName = 'entity.' . $searchable->getColumn(); @@ -44,10 +47,10 @@ public function build(): QueryBuilder } $paramName = 'param_' . str_replace('.', '_', $colName); - $value = $searchable->hasFormatter() ? $searchable->format($searchText) : "%{$searchText}%"; + $value = $searchable->hasFormatter() ? $searchable->format($searchText) : $searchText; $whereDql[] = [ - 'dql' => "{$colName} {$searchable->getOperator()} :{$paramName}", + 'dql' => "$colName {$searchable->getOperator()} :{$paramName}", 'paramName' => $paramName, 'paramValue' => $value ]; @@ -68,9 +71,23 @@ public function build(): QueryBuilder public function keepDefaults(): self { - foreach (['id', 'createdAt', 'updatedAt'] as $columnName) { - $this->addSearchable(new Searchable($columnName)); - } + $this->addSearchable(new Searchable( + column: 'id', + operator: '=', + enabled: fn($value) => UuidV6::isValid($value) + )); + + $this->addSearchable(new Searchable( + column: 'createdAt', + operator: '=', + enabled: fn($value) => \DateTime::createFromFormat('Y-m-d H:i:s', $value) !== false + )); + + $this->addSearchable(new Searchable( + column: 'updatedAt', + operator: '=', + enabled: fn($value) => \DateTime::createFromFormat('Y-m-d H:i:s', $value) !== false + )); return $this; } diff --git a/src/Collection/SearchBuilder/Searchable.php b/src/Collection/SearchBuilder/Searchable.php index f1587ed..6e6d503 100644 --- a/src/Collection/SearchBuilder/Searchable.php +++ b/src/Collection/SearchBuilder/Searchable.php @@ -8,16 +8,24 @@ class Searchable /** @var array */ private array $formatter = []; + /** @var array */ + private array $enabled = []; + public function __construct( protected string $column, protected ?string $relation = null, - protected string $operator = 'LIKE', - ?callable $formatter = null + protected string $operator = '=', + ?callable $formatter = null, + ?callable $enabled = null, ) { if ($formatter !== null) { $this->formatter[] = $formatter; } + + if ($enabled !== null) { + $this->enabled[] = $enabled; + } } public function getColumn(): string @@ -40,6 +48,15 @@ public function format(?string $value): mixed return $this->formatter[0]($value); } + public function isEnabled(?string $value): bool + { + if (count($this->enabled) === 0) { + return true; + } + + return $this->enabled[0]($value); + } + public function hasFormatter(): bool { return count($this->formatter) !== 0; diff --git a/src/Recipe/AdminRecipe.php b/src/Recipe/AdminRecipe.php index 6e57127..b6f9f68 100644 --- a/src/Recipe/AdminRecipe.php +++ b/src/Recipe/AdminRecipe.php @@ -32,8 +32,12 @@ public function search(SearchBuilder $builder, CollectionRequest $request): Sear { $builder ->keepDefaults() - ->addSearchable(new Searchable('email')) - ->addSearchable(new Searchable('lastLogin')); + ->addSearchable(new Searchable('email', operator: 'LIKE', formatter: fn($value) => "%{$value}%")) + ->addSearchable(new Searchable( + column: 'lastLogin', + operator: '=', + enabled: fn($value) => \DateTime::createFromFormat('Y-m-d H:i:s', $value) !== false + )); return $builder; }