-
-
Save alexislefebvre/fcbbb9104c787b9ccb739ce3bb5cfe06 to your computer and use it in GitHub Desktop.
Revisions
-
alexislefebvre revised this gist
Aug 11, 2020 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -22,12 +22,13 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB return; } $orExpressions = []; // Split the $value at spaces. // For each term 'or' all given properties by strategy. // 'And' all 'or'-parts. $terms = explode(" ", $value); foreach ($terms as $index => $term) { foreach ($this->properties as $property => $strategy) { $strategy = $strategy ?? self::STRATEGY_EXACT; -
masseelch revised this gist
Jul 11, 2020 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -86,15 +86,15 @@ protected function addWhereByStrategy(string $strategy, QueryBuilder $queryBuild case self::STRATEGY_EXACT: return $exprBuilder->eq($wrapCase("$alias.$field"), $wrapCase(":$valueParameter")); case self::STRATEGY_PARTIAL: return $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat("'%'", $wrapCase(":$valueParameter"), "'%'")); case self::STRATEGY_START: return $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat($wrapCase(":$valueParameter"), "'%'")); case self::STRATEGY_END: return $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat("'%'", $wrapCase(":$valueParameter"))); case self::STRATEGY_WORD_START: return $exprBuilder->orX( $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat($wrapCase(":$valueParameter"), "'%'")), $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat("'%'", $wrapCase(":$valueParameter"))) ); default: throw new InvalidArgumentException(sprintf('strategy %s does not exist.', $strategy)); -
masseelch revised this gist
Jul 11, 2020 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,7 @@ // Use it like this. /api?search=this_is_my_search_string%20this_is_the_second_term_of_my_search_string <?php /** * @ApiResource() -
masseelch revised this gist
Jul 11, 2020 . 2 changed files with 2 additions and 0 deletions.There are no files selected for viewing
File renamed without changes.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 charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // Use it like this. /** * @ApiResource() * @ApiFilter(FullTextSearchFilter::class, properties={ -
masseelch created this gist
Jul 11, 2020 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,103 @@ <?php namespace App\Filter; use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; use ApiPlatform\Core\Exception\InvalidArgumentException; use Doctrine\ORM\QueryBuilder; class FullTextSearchFilter extends SearchFilter { private const PROPERTY_NAME = 'search'; /** * {@inheritdoc} */ protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) { // This filter will work with the 'search'-query-parameter only. if ($property !== self::PROPERTY_NAME) { return; } // Split the $value at spaces. // For each term 'or' all given properties by strategy. // 'And' all 'or'-parts. $orExpressions = []; $terms = explode(" ", $value); foreach ($terms as $index => $term) { foreach ($this->properties as $property => $strategy) { $strategy = $strategy ?? self::STRATEGY_EXACT; $alias = $queryBuilder->getRootAliases()[0]; $field = $property; $associations = []; if ($this->isPropertyNested($property, $resourceClass)) { [$alias, $field, $associations] = $this->addJoinsForNestedProperty($property, $alias, $queryBuilder, $queryNameGenerator, $resourceClass); } $caseSensitive = true; $metadata = $this->getNestedMetadata($resourceClass, $associations); if ($metadata->hasField($field)) { if ('id' === $field) { $term = $this->getIdFromValue($term); } if (!$this->hasValidValues((array)$term, $this->getDoctrineFieldType($property, $resourceClass))) { $this->logger->notice('Invalid filter ignored', [ 'exception' => new InvalidArgumentException(sprintf('Values for field "%s" are not valid according to the doctrine type.', $field)), ]); continue; } // prefixing the strategy with i makes it case insensitive if (0 === strpos($strategy, 'i')) { $strategy = substr($strategy, 1); $caseSensitive = false; } $orExpressions[$index][] = $this->addWhereByStrategy($strategy, $queryBuilder, $queryNameGenerator, $alias, $field, $term, $caseSensitive); } } } $exprBuilder = $queryBuilder->expr(); foreach ($orExpressions as $expr) { $queryBuilder->andWhere($exprBuilder->orX(...$expr)); } } /** * {@inheritDoc} */ protected function addWhereByStrategy(string $strategy, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $alias, string $field, $value, bool $caseSensitive) { $wrapCase = $this->createWrapCase($caseSensitive); $valueParameter = $queryNameGenerator->generateParameterName($field); $exprBuilder = $queryBuilder->expr(); $queryBuilder->setParameter($valueParameter, $value); switch ($strategy) { case null: case self::STRATEGY_EXACT: return $exprBuilder->eq($wrapCase("$alias.$field"), $wrapCase(":$valueParameter")); case self::STRATEGY_PARTIAL: return $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat('%', $wrapCase(":$valueParameter"), '%')); case self::STRATEGY_START: return $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat($wrapCase(":$valueParameter"), '%')); case self::STRATEGY_END: return $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat('%', $wrapCase(":$valueParameter"))); case self::STRATEGY_WORD_START: return $exprBuilder->orX( $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat($wrapCase(":$valueParameter"), '%')), $exprBuilder->like($wrapCase("$alias.$field"), $exprBuilder->concat('%', $wrapCase(":$valueParameter"))) ); default: throw new InvalidArgumentException(sprintf('strategy %s does not exist.', $strategy)); } } } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,54 @@ /** * @ApiResource() * @ApiFilter(FullTextSearchFilter::class, properties={ * "id": "exact", * "task": "partial", * "client.name": "start" * }) * @ORM\Entity(repositoryClass=EntityRepository::class) */ class Job { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\ManyToOne(targetEntity=Client::class, inversedBy="entites") * @ORM\JoinColumn(nullable=false) */ private $client; public function getId(): ?int { return $this->id; } public function getTask(): ?string { return $this->task; } public function setTask(string $task): self { $this->task = $task; return $this; } public function getClient(): ?Client { return $this->client; } public function setClient(?Client $client): self { $this->client = $client; return $this; } }