Implemented the basics for a parametric search

This commit is contained in:
Jan Böhmer 2022-09-06 00:25:02 +02:00
parent 4d78f8d4e8
commit 9ed953d1b2
8 changed files with 253 additions and 7 deletions

View file

@ -2,6 +2,7 @@
namespace App\DataTables\Filters;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\QueryBuilder;
trait CompoundFilterTrait
@ -23,6 +24,15 @@ trait CompoundFilterTrait
if($value instanceof FilterInterface) {
$filters[$property->getName()] = $value;
}
//Add filters in collections
if ($value instanceof Collection) {
foreach ($value as $key => $filter) {
if($filter instanceof FilterInterface) {
$filters[$property->getName() . '.' . (string) $key] = $filter;
}
}
}
}
return $filters;
}

View file

@ -0,0 +1,116 @@
<?php
namespace App\DataTables\Filters\Constraints\Part;
use App\DataTables\Filters\Constraints\AbstractConstraint;
use App\Entity\Parameters\PartParameter;
use Doctrine\ORM\QueryBuilder;
class ParameterConstraint extends AbstractConstraint
{
/** @var string */
protected $name;
/** @var string */
protected $symbol;
/** @var string */
protected $unit;
public function __construct()
{
parent::__construct("parts.parameters");
}
public function isEnabled(): bool
{
return true;
}
public function apply(QueryBuilder $queryBuilder): void
{
//Create a new qb to build the subquery
$subqb = new QueryBuilder($queryBuilder->getEntityManager());
//The alias has to be uniq for each subquery, so generate a random one
$alias = uniqid('param_', false);
$subqb->select('COUNT(' . $alias . ')')
->from(PartParameter::class, $alias)
->where($alias . '.element = part');
if (!empty($this->name)) {
$paramName = $this->generateParameterIdentifier('params.name');
$subqb->andWhere($alias . '.name = :' . $paramName);
$queryBuilder->setParameter($paramName, $this->name);
}
if (!empty($this->symbol)) {
$paramName = $this->generateParameterIdentifier('params.symbol');
$subqb->andWhere($alias . '.symbol = :' . $paramName);
$queryBuilder->setParameter($paramName, $this->symbol);
}
if (!empty($this->unit)) {
$paramName = $this->generateParameterIdentifier('params.unit');
$subqb->andWhere($alias . '.unit = :' . $paramName);
$queryBuilder->setParameter($paramName, $this->unit);
}
$queryBuilder->andWhere('(' . $subqb->getDQL() . ') > 0');
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
* @return ParameterConstraint
*/
public function setName(string $name): ParameterConstraint
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getSymbol(): string
{
return $this->symbol;
}
/**
* @param string $symbol
* @return ParameterConstraint
*/
public function setSymbol(string $symbol): ParameterConstraint
{
$this->symbol = $symbol;
return $this;
}
/**
* @return string
*/
public function getUnit(): string
{
return $this->unit;
}
/**
* @param string $unit
* @return ParameterConstraint
*/
public function setUnit(string $unit): ParameterConstraint
{
$this->unit = $unit;
return $this;
}
}

View file

@ -8,6 +8,7 @@ use App\DataTables\Filters\Constraints\DateTimeConstraint;
use App\DataTables\Filters\Constraints\EntityConstraint;
use App\DataTables\Filters\Constraints\IntConstraint;
use App\DataTables\Filters\Constraints\NumberConstraint;
use App\DataTables\Filters\Constraints\Part\ParameterConstraint;
use App\DataTables\Filters\Constraints\Part\TagsConstraint;
use App\DataTables\Filters\Constraints\TextConstraint;
use App\Entity\Attachments\AttachmentType;
@ -18,6 +19,7 @@ use App\Entity\Parts\MeasurementUnit;
use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier;
use App\Services\Trees\NodesListBuilder;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\QueryBuilder;
class PartFilter implements FilterInterface
@ -112,6 +114,9 @@ class PartFilter implements FilterInterface
/** @var TextConstraint */
protected $attachmentName;
/** @var ArrayCollection<int, ParameterConstraint> */
protected $parameters;
public function __construct(NodesListBuilder $nodesListBuilder)
{
$this->name = new TextConstraint('part.name');
@ -153,6 +158,8 @@ class PartFilter implements FilterInterface
$this->attachmentName = new TextConstraint('attachments.name');
$this->orderdetailsCount = new IntConstraint('COUNT(orderdetails)');
$this->parameters = new ArrayCollection();
}
public function apply(QueryBuilder $queryBuilder): void
@ -372,5 +379,14 @@ class PartFilter implements FilterInterface
return $this->amountSum;
}
/**
* @return ArrayCollection
*/
public function getParameters(): ArrayCollection
{
return $this->parameters;
}
}

View file

@ -0,0 +1,37 @@
<?php
namespace App\Form\Filters\Constraints;
use App\DataTables\Filters\Constraints\Part\ParameterConstraint;
use Svg\Tag\Text;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SearchType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ParameterConstraintType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'compound' => true,
'data_class' => ParameterConstraint::class,
]);
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('name', TextType::class, [
'required' => false,
]);
$builder->add('unit', SearchType::class, [
'required' => false,
]);
$builder->add('symbol', SearchType::class, [
'required' => false
]);
}
}

View file

@ -13,11 +13,13 @@ use App\Form\Filters\Constraints\BooleanConstraintType;
use App\Form\Filters\Constraints\ChoiceConstraintType;
use App\Form\Filters\Constraints\DateTimeConstraintType;
use App\Form\Filters\Constraints\NumberConstraintType;
use App\Form\Filters\Constraints\ParameterConstraintType;
use App\Form\Filters\Constraints\StructuralEntityConstraintType;
use App\Form\Filters\Constraints\TagsConstraintType;
use App\Form\Filters\Constraints\TextConstraintType;
use Svg\Tag\Text;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\ResetType;
@ -209,6 +211,14 @@ class PartFilterType extends AbstractType
'label' => 'part.filter.attachmentName',
]);
$builder->add('parameters', CollectionType::class, [
'label' => 'parameter.label',
'entry_type' => ParameterConstraintType::class,
'allow_delete' => true,
'allow_add' => true,
'reindex_enable' => false,
]);
$builder->add('submit', SubmitType::class, [
'label' => 'filter.submit',
]);