mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-15 14:49:33 +00:00
Added ID to search options. Fixed seach option by using equal to instead of like for the ID.
This commit is contained in:
parent
2157916e9b
commit
64efca4786
3 changed files with 56 additions and 18 deletions
|
|
@ -319,6 +319,7 @@ class PartListsController extends AbstractController
|
||||||
|
|
||||||
//As an unchecked checkbox is not set in the query, the default value for all bools have to be false (which is the default argument value)!
|
//As an unchecked checkbox is not set in the query, the default value for all bools have to be false (which is the default argument value)!
|
||||||
$filter->setName($request->query->getBoolean('name'));
|
$filter->setName($request->query->getBoolean('name'));
|
||||||
|
$filter->setDbId($request->query->getBoolean('dbid'));
|
||||||
$filter->setCategory($request->query->getBoolean('category'));
|
$filter->setCategory($request->query->getBoolean('category'));
|
||||||
$filter->setDescription($request->query->getBoolean('description'));
|
$filter->setDescription($request->query->getBoolean('description'));
|
||||||
$filter->setMpn($request->query->getBoolean('mpn'));
|
$filter->setMpn($request->query->getBoolean('mpn'));
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
namespace App\DataTables\Filters;
|
namespace App\DataTables\Filters;
|
||||||
use App\DataTables\Filters\Constraints\AbstractConstraint;
|
use App\DataTables\Filters\Constraints\AbstractConstraint;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Doctrine\DBAL\ParameterType;
|
||||||
|
|
||||||
class PartSearchFilter implements FilterInterface
|
class PartSearchFilter implements FilterInterface
|
||||||
{
|
{
|
||||||
|
|
@ -33,6 +34,9 @@ class PartSearchFilter implements FilterInterface
|
||||||
/** @var bool Use name field for searching */
|
/** @var bool Use name field for searching */
|
||||||
protected bool $name = true;
|
protected bool $name = true;
|
||||||
|
|
||||||
|
/** @var bool Use id field for searching */
|
||||||
|
protected bool $dbId = false;
|
||||||
|
|
||||||
/** @var bool Use category name for searching */
|
/** @var bool Use category name for searching */
|
||||||
protected bool $category = true;
|
protected bool $category = true;
|
||||||
|
|
||||||
|
|
@ -120,33 +124,51 @@ class PartSearchFilter implements FilterInterface
|
||||||
public function apply(QueryBuilder $queryBuilder): void
|
public function apply(QueryBuilder $queryBuilder): void
|
||||||
{
|
{
|
||||||
$fields_to_search = $this->getFieldsToSearch();
|
$fields_to_search = $this->getFieldsToSearch();
|
||||||
|
$is_numeric = preg_match('/^\d+$/', $this->keyword) === 1;
|
||||||
|
|
||||||
|
// Add exact ID match only when the keyword is numeric
|
||||||
|
$search_dbId = $is_numeric && (bool)$this->dbId;
|
||||||
|
|
||||||
//If we have nothing to search for, do nothing
|
//If we have nothing to search for, do nothing
|
||||||
if ($fields_to_search === [] || $this->keyword === '') {
|
if (($fields_to_search === [] && !$search_dbId) || $this->keyword === '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Convert the fields to search to a list of expressions
|
$expressions = [];
|
||||||
$expressions = array_map(function (string $field): string {
|
|
||||||
|
if($fields_to_search !== []) {
|
||||||
|
//Convert the fields to search to a list of expressions
|
||||||
|
$expressions = array_map(function (string $field): string {
|
||||||
|
if ($this->regex) {
|
||||||
|
return sprintf("REGEXP(%s, :search_query) = TRUE", $field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf("ILIKE(%s, :search_query) = TRUE", $field);
|
||||||
|
}, $fields_to_search);
|
||||||
|
|
||||||
|
//For regex, we pass the query as is, for like we add % to the start and end as wildcards
|
||||||
if ($this->regex) {
|
if ($this->regex) {
|
||||||
return sprintf("REGEXP(%s, :search_query) = TRUE", $field);
|
$queryBuilder->setParameter('search_query', $this->keyword);
|
||||||
|
} else {
|
||||||
|
//Escape % and _ characters in the keyword
|
||||||
|
$this->keyword = str_replace(['%', '_'], ['\%', '\_'], $this->keyword);
|
||||||
|
$queryBuilder->setParameter('search_query', '%' . $this->keyword . '%');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sprintf("ILIKE(%s, :search_query) = TRUE", $field);
|
//Use equal expression to just search for exact numeric matches
|
||||||
}, $fields_to_search);
|
if ($search_dbId) {
|
||||||
|
$expressions[] = $queryBuilder->expr()->eq('part.id', ':id_exact');
|
||||||
|
$queryBuilder->setParameter('id_exact', (int) $this->keyword,
|
||||||
|
\Doctrine\DBAL\ParameterType::INTEGER);
|
||||||
|
}
|
||||||
|
|
||||||
//Add Or concatenation of the expressions to our query
|
//Guard condition
|
||||||
$queryBuilder->andWhere(
|
if (!empty($expressions)) {
|
||||||
$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) {
|
|
||||||
$queryBuilder->setParameter('search_query', $this->keyword);
|
|
||||||
} else {
|
|
||||||
//Escape % and _ characters in the keyword
|
|
||||||
$this->keyword = str_replace(['%', '_'], ['\%', '\_'], $this->keyword);
|
|
||||||
$queryBuilder->setParameter('search_query', '%' . $this->keyword . '%');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,6 +205,17 @@ class PartSearchFilter implements FilterInterface
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isDbId(): bool
|
||||||
|
{
|
||||||
|
return $this->dbId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDbId(bool $dbId): PartSearchFilter
|
||||||
|
{
|
||||||
|
$this->dbId = $dbId;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function isCategory(): bool
|
public function isCategory(): bool
|
||||||
{
|
{
|
||||||
return $this->category;
|
return $this->category;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@
|
||||||
<input type="checkbox" class="form-check-input" id="search_name" name="name" value="1" checked {{ stimulus_controller('elements/localStorage_checkbox') }}>
|
<input type="checkbox" class="form-check-input" id="search_name" name="name" value="1" checked {{ stimulus_controller('elements/localStorage_checkbox') }}>
|
||||||
<label for="search_name" class="form-check-label justify-content-start">{% trans %}name.label{% endtrans %}</label>
|
<label for="search_name" class="form-check-label justify-content-start">{% trans %}name.label{% endtrans %}</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" id="search_dbid" name="dbid" value="1" checked {{ stimulus_controller('elements/localStorage_checkbox') }}>
|
||||||
|
<label for="search_dbid" class="form-check-label justify-content-start">{% trans %}id.label{% endtrans %}</label>
|
||||||
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input type="checkbox" class="form-check-input" id="search_category" name="category" value="1" checked {{ stimulus_controller('elements/localStorage_checkbox') }}>
|
<input type="checkbox" class="form-check-input" id="search_category" name="category" value="1" checked {{ stimulus_controller('elements/localStorage_checkbox') }}>
|
||||||
<label for="search_category" class="form-check-label justify-content-start">{% trans %}category.label{% endtrans %}</label>
|
<label for="search_category" class="form-check-label justify-content-start">{% trans %}category.label{% endtrans %}</label>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue