[FilterOrder] add a method to get all the active filters

This commit is contained in:
Julien Fastré 2023-07-10 15:26:54 +02:00
parent ca62c3fd0b
commit 39896ea6e2
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
7 changed files with 126 additions and 26 deletions

View File

@ -47,16 +47,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
$checkboxesBuilder = $builder->create('checkboxes', null, ['compound' => true]);
foreach ($helper->getCheckboxes() as $name => $c) {
$choices = array_combine(
array_map(static function ($c, $t) {
if (null !== $t) {
return $t;
}
return $c;
}, $c['choices'], $c['trans']),
$c['choices']
);
$choices = self::buildCheckboxChoices($c['choices'], $c['trans']);
$checkboxesBuilder->add($name, ChoiceType::class, [
'choices' => $choices,
@ -125,6 +116,20 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
}
}
public static function buildCheckboxChoices(array $choices, array $trans = []): array
{
return array_combine(
array_map(static function ($c, $t) {
if (null !== $t) {
return $t;
}
return $c;
}, $choices, $trans),
$choices
);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
/** @var FilterOrderHelper $helper */

View File

@ -93,6 +93,17 @@
{% endif %}
</div>
</div>
{% set active = helper.getActiveFilters() %}
{% if active|length > 0 %}
<div>
{% for f in active %}
<span class="{{ f.position }} {{ f.name }}">{% if f.label != '' %}{{ f.label|trans }}&nbsp;: {% endif %}{{ f.value }}</span>
{% endfor %}
</div>
{% endif %}
<div>
</div>
</div>
{% for k,v in otherParameters %}

View File

@ -13,16 +13,19 @@ namespace Chill\MainBundle\Templating\Listing;
use Chill\MainBundle\Form\Type\Listing\FilterOrderType;
use DateTimeImmutable;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\PropertyAccess\PropertyAccessor;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyPathInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use function array_merge;
use function count;
class FilterOrderHelper
final class FilterOrderHelper
{
private array $checkboxes = [];
@ -33,16 +36,12 @@ class FilterOrderHelper
private array $dateRanges = [];
private FormFactoryInterface $formFactory;
public const FORM_NAME = 'f';
private array $formOptions = [];
private string $formType = FilterOrderType::class;
private RequestStack $requestStack;
private ?array $searchBoxFields = null;
private ?array $submitted = null;
@ -52,12 +51,13 @@ class FilterOrderHelper
*/
private array $entityChoices = [];
public function __construct(
FormFactoryInterface $formFactory,
RequestStack $requestStack
private readonly FormFactoryInterface $formFactory,
private readonly RequestStack $requestStack,
private readonly TranslatorInterface $translator,
private readonly PropertyAccessorInterface $propertyAccessor,
) {
$this->formFactory = $formFactory;
$this->requestStack = $requestStack;
}
public function addSingleCheckbox(string $name, string $label): self
@ -199,6 +199,63 @@ class FilterOrderHelper
return $this;
}
/**
* Return all the data required to display the active filters
*
* @return array<array{label: string, value: string, position: string, name: string}>
*/
public function getActiveFilters(): array
{
$result = [];
if ($this->hasSearchBox() && '' !== $this->getQueryString()) {
$result[] = ['label' => '', 'value' => $this->getQueryString(), 'position' => FilterOrderPositionEnum::SearchBox->value, 'name' => 'q'];
}
foreach ($this->dateRanges as $name => ['label' => $label]) {
$base = ['position' => FilterOrderPositionEnum::DateRange->value, 'name' => $name, 'label' => (string) $label];
if (null !== ($from = $this->getDateRangeData($name)['from'] ?? null)) {
$result[] = ['value' => $this->translator->trans('filter_order.by_date.From', ['from_date' => $from]), ...$base];
}
if (null !== ($to = $this->getDateRangeData($name)['to'] ?? null)) {
$result[] = ['value' => $this->translator->trans('filter_order.by_date.To', ['to_date' => $to]), ...$base];
}
}
foreach ($this->checkboxes as $name => ['choices' => $choices, 'trans' => $trans, 'options' => $options]) {
foreach ($this->getCheckboxData($name) as $keyChoice) {
$result[] = ['value' => $choices['keyChoice'], 'label' => $options['label'], 'position' => FilterOrderPositionEnum::Checkboxes->value, 'name' => $name];
}
}
foreach ($this->entityChoices as $name => ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]) {
foreach ($this->getEntityChoiceData($name) as $selected) {
if (is_callable($options['choice_label'])) {
$value = call_user_func($options['choice_label'], $selected);
} elseif ($options['choice_label'] instanceof PropertyPathInterface || is_string($options['choice_label'])) {
$value = $this->propertyAccessor->getValue($selected, $options['choice_label']);
} else {
if (!$selected instanceof \Stringable) {
throw new \UnexpectedValueException(sprintf("we are not able to transform the value of %s to a string. Implements \Stringable or add a 'choice_label' option to the filterFormBuilder", get_class($selected)));
}
$value = (string) $selected;
}
$result[] = ['value' => $value, 'label' => $label, 'position' => FilterOrderPositionEnum::EntityChoice->value, 'name' => $name];
}
}
foreach ($this->singleCheckbox as $name => ['label' => $label]) {
if (true === $this->getSingleCheckboxData($name)) {
$result[] = ['label' => '', 'value' => $this->translator->trans($label), 'position' => FilterOrderPositionEnum::SingleCheckbox->value, 'name' => $name];
}
}
return $result;
}
private function getDefaultData(): array
{
$r = [

View File

@ -14,6 +14,8 @@ namespace Chill\MainBundle\Templating\Listing;
use DateTimeImmutable;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class FilterOrderHelperBuilder
{
@ -39,7 +41,9 @@ class FilterOrderHelperBuilder
public function __construct(
FormFactoryInterface $formFactory,
RequestStack $requestStack
RequestStack $requestStack,
private readonly TranslatorInterface $translator,
private readonly PropertyAccessorInterface $propertyAccessor,
) {
$this->formFactory = $formFactory;
$this->requestStack = $requestStack;
@ -87,7 +91,9 @@ class FilterOrderHelperBuilder
{
$helper = new FilterOrderHelper(
$this->formFactory,
$this->requestStack
$this->requestStack,
$this->translator,
$this->propertyAccessor
);
$helper->setSearchBox($this->searchBoxFields);

View File

@ -13,6 +13,8 @@ namespace Chill\MainBundle\Templating\Listing;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface
{
@ -22,7 +24,9 @@ class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface
public function __construct(
FormFactoryInterface $formFactory,
RequestStack $requestStack
RequestStack $requestStack,
private readonly TranslatorInterface $translator,
private readonly PropertyAccessorInterface $propertyAccessor,
) {
$this->formFactory = $formFactory;
$this->requestStack = $requestStack;
@ -30,6 +34,6 @@ class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface
public function create(string $context, ?array $options = []): FilterOrderHelperBuilder
{
return new FilterOrderHelperBuilder($this->formFactory, $this->requestStack);
return new FilterOrderHelperBuilder($this->formFactory, $this->requestStack, $this->translator, $this->propertyAccessor);
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Chill\MainBundle\Templating\Listing;
enum FilterOrderPositionEnum: string
{
case SearchBox = 'search_box';
case Checkboxes = 'checkboxes';
case DateRange = 'date_range';
case EntityChoice = 'entity_choice';
case SingleCheckbox = 'single_checkbox';
}

View File

@ -54,3 +54,8 @@ duration:
few {# minutes}
other {# minutes}
}
filter_order:
by_date:
From: Depuis le {from_date, date, long}
To: Jusqu'au {to_date, date, long}