Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 45 additions & 15 deletions src/DataTables/Filters/PartSearchFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,16 @@
/** @var bool Use Internal Part number for searching */
protected bool $ipn = true;

/** @var int Helper variable for hacky array_map variable injection */
protected int $it = 0;

public function __construct(
/** @var string The string to query for */
protected string $keyword
)
{
// Transform keyword and trim excess spaces
$keyword = trim(str_replace('+', ' ', $keyword));
}

protected function getFieldsToSearch(): array
Expand Down Expand Up @@ -126,27 +131,53 @@
return;
}

//Convert the fields to search to a list of expressions
$expressions = array_map(function (string $field): string {
if ($this->regex) {
if($this->regex) {
//Convert the fields to search to a list of expressions
$expressions = array_map(function (string $field): string {
return sprintf("REGEXP(%s, :search_query) = TRUE", $field);
}
}, $fields_to_search);

return sprintf("ILIKE(%s, :search_query) = TRUE", $field);
}, $fields_to_search);
//Add Or concatenation of the expressions to our query
$queryBuilder->andWhere(
$queryBuilder->expr()->orX(...$expressions)
);

//Add Or concatenation of the expressions to our query
$queryBuilder->andWhere(
$queryBuilder->expr()->orX(...$expressions)
);

//For regex, we pass the query as is, for like we add % to the start and end as wildcards
if ($this->regex) {
//For regex, we pass the query as is, save html special chars
$queryBuilder->setParameter('search_query', $this->keyword);
return;
} else {
//Escape % and _ characters in the keyword
$this->keyword = str_replace(['%', '_'], ['\%', '\_'], $this->keyword);
$queryBuilder->setParameter('search_query', '%' . $this->keyword . '%');

//Split keyword on spaces, but limit token count
$tokens = explode(' ', $this->keyword, 5);

$params = new \Doctrine\Common\Collections\ArrayCollection();

//Perform search of every single token in every selected field
//AND-combine the results (all tokens must be present in any result, but the order does not matter)
for ($i = 0; $i < sizeof($tokens); $i++) {
$this->it = $i;
$tokens[$i] = trim($tokens[$i]);

//Skip empty words (e.g. because of multiple spaces)
if ($tokens[$i] === '') {
continue;
}
//Convert the fields to search to a list of expressions
$expressions = array_map(function (string $field): string {
return sprintf("ILIKE(%s, :search_query%u) = TRUE", $field, $this->it);
}, $fields_to_search);

//Aggregate the parameters for consolidated commission
$params[] = new \Doctrine\ORM\Query\Parameter('search_query' . $i, '%' . $tokens[$i] . '%');

Check failure on line 173 in src/DataTables/Filters/PartSearchFilter.php

View workflow job for this annotation

GitHub Actions / Static analysis

Doctrine\Common\Collections\ArrayCollection<*NEVER*, *NEVER*> does not accept Doctrine\ORM\Query\Parameter.

//Add Or concatenation of the expressions to our query
$queryBuilder->andWhere(
$queryBuilder->expr()->orX(...$expressions)
);
}
$queryBuilder->setParameters($params);
}
}

Expand Down Expand Up @@ -304,5 +335,4 @@
return $this;
}


}
Loading