mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-20 17:15:51 +02:00
Search options now working. Added Regex search.
This commit is contained in:
parent
120eb30b11
commit
86ee10e582
7 changed files with 274 additions and 50 deletions
|
@ -10,6 +10,7 @@
|
|||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"beberlei/doctrineextensions": "^1.2",
|
||||
"doctrine/annotations": "^1.6",
|
||||
"doctrine/doctrine-bundle": "^2.0",
|
||||
"florianv/swap": "^4.0",
|
||||
|
@ -20,8 +21,8 @@
|
|||
"nyholm/psr7": "^1.1",
|
||||
"ocramius/proxy-manager": "2.2.*",
|
||||
"omines/datatables-bundle": "^0.4.0",
|
||||
"r/u2f-two-factor-bundle": "dev-u2f-api",
|
||||
"php-translation/symfony-bundle": "^0.12.0",
|
||||
"r/u2f-two-factor-bundle": "dev-u2f-api",
|
||||
"s9e/text-formatter": "^2.1",
|
||||
"scheb/two-factor-bundle": "^4.11",
|
||||
"sensio/framework-extra-bundle": "^5.1",
|
||||
|
|
56
composer.lock
generated
56
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ef069d33ff96f4e5e05b11f1d2189dfc",
|
||||
"content-hash": "6ebc8e9705e901be6f00f9f6418cf900",
|
||||
"packages": [
|
||||
{
|
||||
"name": "beberlei/assert",
|
||||
|
@ -68,6 +68,60 @@
|
|||
],
|
||||
"time": "2019-12-19T17:51:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beberlei/doctrineextensions",
|
||||
"version": "v1.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/beberlei/DoctrineExtensions.git",
|
||||
"reference": "af72c4a136b744f1268ca8bb4da47a2f8af78f86"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/beberlei/DoctrineExtensions/zipball/af72c4a136b744f1268ca8bb4da47a2f8af78f86",
|
||||
"reference": "af72c4a136b744f1268ca8bb4da47a2f8af78f86",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/orm": "^2.6",
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.14",
|
||||
"nesbot/carbon": "*",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0",
|
||||
"symfony/yaml": "^4.2",
|
||||
"zf1/zend-date": "^1.12",
|
||||
"zf1/zend-registry": "^1.12"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DoctrineExtensions\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Steve Lacey",
|
||||
"email": "steve@stevelacey.net"
|
||||
}
|
||||
],
|
||||
"description": "A set of extensions to Doctrine 2 that add support for additional query functions available in MySQL and Oracle.",
|
||||
"keywords": [
|
||||
"database",
|
||||
"doctrine",
|
||||
"orm"
|
||||
],
|
||||
"time": "2019-12-05T09:49:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "v1.8.0",
|
||||
|
|
|
@ -26,3 +26,7 @@ doctrine:
|
|||
dir: '%kernel.project_dir%/src/Entity'
|
||||
prefix: 'App\Entity'
|
||||
alias: App
|
||||
|
||||
dql:
|
||||
string_functions:
|
||||
regexp: DoctrineExtensions\Query\Mysql\Regexp
|
|
@ -204,8 +204,24 @@ class PartListsController extends AbstractController
|
|||
public function showSearch(Request $request, DataTableFactory $dataTable)
|
||||
{
|
||||
$search = $request->query->get('keyword', '');
|
||||
$search_options = [
|
||||
'name' => $request->query->getBoolean('name'),
|
||||
'description' => $request->query->getBoolean('description'),
|
||||
'comment' => $request->query->getBoolean('comment'),
|
||||
'category' => $request->query->getBoolean('category'),
|
||||
'store_location' => $request->query->getBoolean('storelocation'),
|
||||
'supplier' => $request->query->getBoolean('supplier'),
|
||||
'ordernr' => $request->query->getBoolean('ordernr'),
|
||||
'manufacturer' => $request->query->getBoolean('manufacturer'),
|
||||
'footprint' => $request->query->getBoolean('footprint'),
|
||||
'tags' => $request->query->getBoolean('tags'),
|
||||
'regex' => $request->query->getBoolean('regex'),
|
||||
];
|
||||
|
||||
$table = $dataTable->createFromType(PartsDataTable::class, ['search' => $search])
|
||||
|
||||
$table = $dataTable->createFromType(PartsDataTable::class, [
|
||||
'search' => $search, 'search_options' => $search_options
|
||||
])
|
||||
->handleRequest($request);
|
||||
|
||||
if ($table->isCallback()) {
|
||||
|
|
|
@ -66,6 +66,7 @@ use Omines\DataTablesBundle\Column\MapColumn;
|
|||
use Omines\DataTablesBundle\Column\TextColumn;
|
||||
use Omines\DataTablesBundle\DataTable;
|
||||
use Omines\DataTablesBundle\DataTableTypeInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
final class PartsDataTable implements DataTableTypeInterface
|
||||
|
@ -81,8 +82,8 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
private $urlGenerator;
|
||||
|
||||
public function __construct(EntityURLGenerator $urlGenerator, TranslatorInterface $translator,
|
||||
NodesListBuilder $treeBuilder, AmountFormatter $amountFormatter,
|
||||
PartPreviewGenerator $previewGenerator, AttachmentURLGenerator $attachmentURLGenerator)
|
||||
NodesListBuilder $treeBuilder, AmountFormatter $amountFormatter,
|
||||
PartPreviewGenerator $previewGenerator, AttachmentURLGenerator $attachmentURLGenerator)
|
||||
{
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->translator = $translator;
|
||||
|
@ -92,8 +93,59 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
$this->attachmentURLGenerator = $attachmentURLGenerator;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $optionsResolver)
|
||||
{
|
||||
$optionsResolver->setDefaults([
|
||||
'category' => null,
|
||||
'footprint' => null,
|
||||
'manufacturer' => null,
|
||||
'storelocation' => null,
|
||||
'supplier' => null,
|
||||
'tag' => null,
|
||||
'search' => null,
|
||||
]);
|
||||
|
||||
$optionsResolver->setAllowedTypes('category', ['null', Category::class]);
|
||||
$optionsResolver->setAllowedTypes('footprint', ['null', Footprint::class]);
|
||||
$optionsResolver->setAllowedTypes('manufacturer', ['null', Manufacturer::class]);
|
||||
$optionsResolver->setAllowedTypes('supplier', ['null', Supplier::class]);
|
||||
$optionsResolver->setAllowedTypes('tag', ['null', 'string']);
|
||||
$optionsResolver->setAllowedTypes('search', ['null', 'string']);
|
||||
|
||||
//Configure search options
|
||||
$optionsResolver->setDefault('search_options', function (OptionsResolver $resolver) {
|
||||
$resolver->setDefaults([
|
||||
'name' => true,
|
||||
'category' => true,
|
||||
'description' => true,
|
||||
'store_location' => true,
|
||||
'comment' => true,
|
||||
'ordernr' => true,
|
||||
'supplier' => false,
|
||||
'manufacturer' => false,
|
||||
'footprint' => false,
|
||||
'tags' => false,
|
||||
'regex' => false,
|
||||
]);
|
||||
$resolver->setAllowedTypes('name', 'bool');
|
||||
$resolver->setAllowedTypes('category', 'bool');
|
||||
$resolver->setAllowedTypes('description', 'bool');
|
||||
$resolver->setAllowedTypes('store_location', 'bool');
|
||||
$resolver->setAllowedTypes('comment', 'bool');
|
||||
$resolver->setAllowedTypes('supplier', 'bool');
|
||||
$resolver->setAllowedTypes('manufacturer', 'bool');
|
||||
$resolver->setAllowedTypes('footprint', 'bool');
|
||||
$resolver->setAllowedTypes('tags', 'bool');
|
||||
$resolver->setAllowedTypes('regex', 'bool');
|
||||
});
|
||||
}
|
||||
|
||||
public function configure(DataTable $dataTable, array $options): void
|
||||
{
|
||||
$resolver = new OptionsResolver();
|
||||
$this->configureOptions($resolver);
|
||||
$options = $resolver->resolve($options);
|
||||
|
||||
$dataTable
|
||||
->add('picture', TextColumn::class, [
|
||||
'label' => '',
|
||||
|
@ -270,6 +322,7 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
->leftJoin('footprint.master_picture_attachment', 'footprint_attachment')
|
||||
->leftJoin('part.manufacturer', 'manufacturer')
|
||||
->leftJoin('part.orderdetails', 'orderdetails')
|
||||
->leftJoin('orderdetails.supplier', 'suppliers')
|
||||
->leftJoin('part.attachments', 'attachments')
|
||||
->leftJoin('part.partUnit', 'partUnit');
|
||||
}
|
||||
|
@ -322,9 +375,96 @@ final class PartsDataTable implements DataTableTypeInterface
|
|||
$builder->andWhere('part.tags LIKE :tag')->setParameter('tag', '%'.$options['tag'].'%');
|
||||
}
|
||||
|
||||
if (isset($options['search'])) {
|
||||
$builder->AndWhere('part.name LIKE :search')->orWhere('part.description LIKE :search')->orWhere('part.comment LIKE :search')
|
||||
->setParameter('search', '%'.$options['search'].'%');
|
||||
if (!empty($options['search'])) {
|
||||
if (!$options['search_options']['regex']) {
|
||||
//Dont show results, if no things are selected
|
||||
$builder->andWhere('0=1');
|
||||
$defined = false;
|
||||
if ($options['search_options']['name']) {
|
||||
$builder->orWhere('part.name LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['description']) {
|
||||
$builder->orWhere('part.description LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['comment']) {
|
||||
$builder->orWhere('part.comment LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['category']) {
|
||||
$builder->orWhere('category.name LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['manufacturer']) {
|
||||
$builder->orWhere('manufacturer.name LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['footprint']) {
|
||||
$builder->orWhere('footprint.name LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['tags']) {
|
||||
$builder->orWhere('part.tags LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['store_location']) {
|
||||
$builder->orWhere('storelocations.name LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['supplier']) {
|
||||
$builder->orWhere('suppliers.name LIKE :search');
|
||||
$defined = true;
|
||||
}
|
||||
|
||||
if ($defined) {
|
||||
$builder->setParameter('search', '%'.$options['search'].'%');
|
||||
}
|
||||
} else { //Use REGEX
|
||||
$builder->andWhere('0=1');
|
||||
$defined = false;
|
||||
if ($options['search_options']['name']) {
|
||||
$builder->orWhere('REGEXP(part.name, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['description']) {
|
||||
$builder->orWhere('REGEXP(part.description, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['comment']) {
|
||||
$builder->orWhere('REGEXP(part.comment, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['category']) {
|
||||
$builder->orWhere('REGEXP(category.name, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['manufacturer']) {
|
||||
$builder->orWhere('REGEXP(manufacturer.name, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['footprint']) {
|
||||
$builder->orWhere('REGEXP(footprint.name, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['tags']) {
|
||||
$builder->orWhere('REGEXP(part.tags, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['store_location']) {
|
||||
$builder->orWhere('REGEXP(storelocations.name, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
if ($options['search_options']['supplier']) {
|
||||
$builder->orWhere('REGEXP(suppliers.name, :search) = 1');
|
||||
$defined = true;
|
||||
}
|
||||
|
||||
if ($defined) {
|
||||
$builder->setParameter('search', $options['search']);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
"beberlei/assert": {
|
||||
"version": "v3.2.6"
|
||||
},
|
||||
"beberlei/doctrineextensions": {
|
||||
"version": "v1.2.6"
|
||||
},
|
||||
"composer/semver": {
|
||||
"version": "1.5.0"
|
||||
},
|
||||
|
|
|
@ -4,56 +4,62 @@
|
|||
{% trans %}search.options.label{% endtrans %}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<div class="dropdown-menu p-2" aria-labelledby="SearchOptions">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_name" name="search_name" value="true" checked>
|
||||
<label for="search_name" class="custom-control-label">{% trans %}name.label{% endtrans %}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_category" name="search_category" value="true" checked>
|
||||
<label for="search_category" class="custom-control-label">{% trans %}category.label{% endtrans %}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_description" name="search_description" value="true" checked>
|
||||
<label for="search_description" class="custom-control-label"></label>{% trans %}description.label{% endtrans %}
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_storelocation" name="search_storelocation" value="true" checked>
|
||||
<label for="search_storelocation" class="custom-control-label">{% trans %}storelocation.label{% endtrans %}</label>
|
||||
</div>
|
||||
<div class=" custom-control custom-checkbox">
|
||||
<input type="checkbox" id="search_comment" class="custom-control-input" id="search_comment" name="search_comment" value="true" checked>
|
||||
<label for="search_comment" class="custom-control-label">{% trans %}comment.label{% endtrans %}</label>
|
||||
</div>
|
||||
{% if true %}
|
||||
<div class="dropdown-menu" aria-labelledby="SearchOptions">
|
||||
<div class="px-1 py-2">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_supplierpartnr" name="search_supplierpartnr" value="true" checked>
|
||||
<label for="search_supplierpartnr" class="custom-control-label">{% trans %}ordernumber.label.short{% endtrans %}</label>
|
||||
<input type="checkbox" class="custom-control-input" id="search_name" name="name" value="1" checked>
|
||||
<label for="search_name" class="custom-control-label justify-content-start">{% trans %}name.label{% endtrans %}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_supplier" name="search_supplier" value="true">
|
||||
<label for="search_supplier" class="custom-control-label">{% trans %}supplier.label{% endtrans %}</label>
|
||||
<input type="checkbox" class="custom-control-input" id="search_category" name="category" value="1" checked>
|
||||
<label for="search_category" class="custom-control-label justify-content-start">{% trans %}category.label{% endtrans %}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if true %}
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_manufacturer" name="search_manufacturer" value="true">
|
||||
<label for="search_manufacturer" class="custom-control-label">{% trans %}manufacturer.label{% endtrans %}</label>
|
||||
<input type="checkbox" class="custom-control-input" id="search_description" name="description" value="1" checked>
|
||||
<label for="search_description" class="custom-control-label justify-content-start">{% trans %}description.label{% endtrans %}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if true %}
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_footprint" name="search_footprint" value="true">
|
||||
<label for="search_footprint" class="custom-control-label">{% trans %}footprint.label{% endtrans %}</label>
|
||||
<input type="checkbox" class="custom-control-input" id="search_tags" name="tags" value="1" checked>
|
||||
<label for="search_tags" class="custom-control-label justify-content-start">{% trans %}tags.label{% endtrans %}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_storelocation" name="storelocation" value="1" checked>
|
||||
<label for="search_storelocation" class="custom-control-label justify-content-start">{% trans %}storelocation.label{% endtrans %}</label>
|
||||
</div>
|
||||
<div class=" custom-control custom-checkbox">
|
||||
<input type="checkbox" id="search_comment" class="custom-control-input" id="search_comment" name="comment" value="1" checked>
|
||||
<label for="search_comment" class="custom-control-label justify-content-start">{% trans %}comment.label{% endtrans %}</label>
|
||||
</div>
|
||||
{% if true %}
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_supplierpartnr" name="ordernr" value="1" checked>
|
||||
<label for="search_supplierpartnr" class="custom-control-label justify-content-start">{% trans %}ordernumber.label.short{% endtrans %}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_supplier" name="supplier" value="1">
|
||||
<label for="search_supplier" class="custom-control-label justify-content-start">{% trans %}supplier.label{% endtrans %}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if true %}
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_manufacturer" name="manufacturer" value="1">
|
||||
<label for="search_manufacturer" class="custom-control-label justify-content-start">{% trans %}manufacturer.label{% endtrans %}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if true %}
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="search_footprint" name="footprint" value="1">
|
||||
<label for="search_footprint" class="custom-control-label justify-content-start">{% trans %}footprint.label{% endtrans %}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="disable_pid_input" name="disable_pid_input" value="1">
|
||||
<label for="disable_pid_input" class="custom-control-label justify-content-start">{% trans %}search.deactivateBarcode{% endtrans %}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="regex" name="regex" value="1">
|
||||
<label for="regex" class="custom-control-label justify-content-start">{% trans %}search.regexmatching{% endtrans %}</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="disable_pid_input" name="disable_pid_input" value="false">
|
||||
<label for="disable_pid_input" class="custom-control-label">{% trans %}search.deactivateBarcode{% endtrans %}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="regex" name="regex" value="true">
|
||||
<label for="regex" class="custom-control-label">{% trans %}search.regexmatching{% endtrans %}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue