diff --git a/.changes/unreleased/DX-20230623-122408.yaml b/.changes/unreleased/DX-20230623-122408.yaml new file mode 100644 index 000000000..58dd96180 --- /dev/null +++ b/.changes/unreleased/DX-20230623-122408.yaml @@ -0,0 +1,5 @@ +kind: DX +body: '[FilterOrderHelper] add entity choice and singleCheckbox' +time: 2023-06-23T12:24:08.133491895+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php index aaa6afa24..16038515d 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php @@ -13,6 +13,8 @@ namespace Chill\MainBundle\Form\Type\Listing; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\SearchType; @@ -27,13 +29,6 @@ use function count; final class FilterOrderType extends \Symfony\Component\Form\AbstractType { - private RequestStack $requestStack; - - public function __construct(RequestStack $requestStack) - { - $this->requestStack = $requestStack; - } - public function buildForm(FormBuilderInterface $builder, array $options) { /** @var FilterOrderHelper $helper */ @@ -71,6 +66,25 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $builder->add($checkboxesBuilder); } + if ([] !== $helper->getEntityChoices()) { + $entityChoicesBuilder = $builder->create('entity_choices', null, ['compound' => true]); + + foreach ($helper->getEntityChoices() as $key => [ + 'label' => $label, 'choices' => $choices, 'options' => $opts, 'class' => $class + ]) { + $entityChoicesBuilder->add($key, EntityType::class, [ + 'label' => $label, + 'choices' => $choices, + 'class' => $class, + 'multiple' => true, + 'expanded' => true, + ...$opts, + ]); + } + + $builder->add($entityChoicesBuilder); + } + if (0 < count($helper->getDateRanges())) { $dateRangesBuilder = $builder->create('dateRanges', null, ['compound' => true]); @@ -97,28 +111,14 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType $builder->add($dateRangesBuilder); } - foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) { - switch ($key) { - case 'q': - case 'checkboxes' . $key: - case $key . '_from': - case $key . '_to': - break; + if ([] !== $helper->getSingleCheckbox()) { + $singleCheckBoxBuilder = $builder->create('single_checkboxes', null, ['compound' => true]); - case 'page': - $builder->add($key, HiddenType::class, [ - 'data' => 1, - ]); - - break; - - default: - $builder->add($key, HiddenType::class, [ - 'data' => $value, - ]); - - break; + foreach ($helper->getSingleCheckbox() as $name => ['label' => $label]) { + $singleCheckBoxBuilder->add($name, CheckboxType::class, ['label' => $label, 'required' => false]); } + + $builder->add($singleCheckBoxBuilder); } } diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig index 1f1e54c72..d4a6bbdd4 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig @@ -13,13 +13,13 @@ {% if form.dateRanges is defined %} {% if form.dateRanges|length > 0 %} {% for dateRangeName, _o in form.dateRanges %} -
+
{% if form.dateRanges[dateRangeName].vars.label is not same as(false) %} -
+
{{ form_label(form.dateRanges[dateRangeName])}}
{% endif %} -
+
{{ 'chill_calendar.From'|trans }} {{ form_widget(form.dateRanges[dateRangeName]['from']) }} @@ -27,7 +27,7 @@ {{ form_widget(form.dateRanges[dateRangeName]['to']) }}
-
+
@@ -37,7 +37,7 @@ {% if form.checkboxes is defined %} {% if form.checkboxes|length > 0 %} {% for checkbox_name, options in form.checkboxes %} -
+
{% for c in form['checkboxes'][checkbox_name].children %}
@@ -61,5 +61,45 @@ {% endfor %} {% endif %} {% endif %} + {% if form.entity_choices is defined %} + {% if form.entity_choices |length > 0 %} + {% for checkbox_name, options in form.entity_choices %} +
+ {% if form.entity_choices[checkbox_name].vars.label is not same as(false) %} +
+ {{ form_label(form.entity_choices[checkbox_name])}} +
+ {% endif %} +
+ {% for c in form['entity_choices'][checkbox_name].children %} +
+ {{ form_widget(c) }} + {{ form_label(c) }} +
+ {% endfor %} +
+
+ +
+
+ {% endfor %} + {% endif %} + {% endif %} + {% if form.single_checkboxes is defined %} + {% for name, _o in form.single_checkboxes %} +
+
+ {{ form_widget(form.single_checkboxes[name]) }} +
+
+ +
+
+ {% endfor %} + {% endif %}
+ + {% for k,v in otherParameters %} + + {% endfor %} {{ form_end(form) }} diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php index 367cc0861..28cc8e331 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php @@ -13,6 +13,8 @@ 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; @@ -24,11 +26,16 @@ class FilterOrderHelper { private array $checkboxes = []; + /** + * @var array + */ + private array $singleCheckbox = []; + private array $dateRanges = []; private FormFactoryInterface $formFactory; - private ?string $formName = 'f'; + public const FORM_NAME = 'f'; private array $formOptions = []; @@ -40,6 +47,11 @@ class FilterOrderHelper private ?array $submitted = null; + /** + * @var array + */ + private array $entityChoices = []; + public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack @@ -48,7 +60,29 @@ class FilterOrderHelper $this->requestStack = $requestStack; } - public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = []): self + public function addSingleCheckbox(string $name, string $label): self + { + $this->singleCheckbox[$name] = ['label' => $label]; + + return $this; + } + + /** + * @param class-string $class + */ + public function addEntityChoice(string $name, string $class, string $label, array $choices, array $options = []): self + { + $this->entityChoices[$name] = ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]; + + return $this; + } + + public function getEntityChoices(): array + { + return $this->entityChoices; + } + + public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = [], array $options = []): self { $missing = count($choices) - count($trans) - 1; $this->checkboxes[$name] = [ @@ -58,6 +92,7 @@ class FilterOrderHelper 0 < $missing ? array_fill(0, $missing, null) : [] ), + ...$options, ]; return $this; @@ -73,7 +108,7 @@ class FilterOrderHelper public function buildForm(): FormInterface { return $this->formFactory - ->createNamed($this->formName, $this->formType, $this->getDefaultData(), array_merge([ + ->createNamed(self::FORM_NAME, $this->formType, $this->getDefaultData(), array_merge([ 'helper' => $this, 'method' => 'GET', 'csrf_protection' => false, @@ -86,13 +121,31 @@ class FilterOrderHelper return $this->getFormData()['checkboxes'][$name]; } + public function getSingleCheckboxData(string $name): ?bool + { + return $this->getFormData()['single_checkboxes'][$name]; + } + + public function getEntityChoiceData($name): mixed + { + return $this->getFormData()['entity_choices'][$name]; + } + public function getCheckboxes(): array { return $this->checkboxes; } /** - * @return array<'to': DateTimeImmutable, 'from': DateTimeImmutable> + * @return array + */ + public function getSingleCheckbox(): array + { + return $this->singleCheckbox; + } + + /** + * @return array{to: ?DateTimeImmutable, from: ?DateTimeImmutable} */ public function getDateRangeData(string $name): array { @@ -123,7 +176,12 @@ class FilterOrderHelper private function getDefaultData(): array { - $r = []; + $r = [ + 'checkboxes' => [], + 'dateRanges' => [], + 'single_checkboxes' => [], + 'entity_choices' => [] + ]; if ($this->hasSearchBox()) { $r['q'] = ''; @@ -138,6 +196,14 @@ class FilterOrderHelper $r['dateRanges'][$name]['to'] = $defaults['to']; } + foreach ($this->singleCheckbox as $name => $c) { + $r['single_checkboxes'][$name] = false; + } + + foreach ($this->entityChoices as $name => $c) { + $r['entity_choices'][$name] = ($c['options']['multiple'] ?? true) ? [] : null; + } + return $r; } diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php index d68c8c37a..e176e27c6 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelperBuilder.php @@ -27,6 +27,16 @@ class FilterOrderHelperBuilder private ?array $searchBoxFields = null; + /** + * @var array + */ + private array $singleCheckboxes = []; + + /** + * @var array + */ + private array $entityChoices = []; + public function __construct( FormFactoryInterface $formFactory, RequestStack $requestStack @@ -35,6 +45,13 @@ class FilterOrderHelperBuilder $this->requestStack = $requestStack; } + public function addSingleCheckbox(string $name, string $label): self + { + $this->singleCheckboxes[$name] = ['label' => $label]; + + return $this; + } + public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = []): self { $this->checkboxes[$name] = ['choices' => $choices, 'default' => $default, 'trans' => $trans]; @@ -42,6 +59,16 @@ class FilterOrderHelperBuilder return $this; } + /** + * @param class-string $class + */ + public function addEntityChoice(string $name, string $label, string $class, array $choices, ?array $options = []): self + { + $this->entityChoices[$name] = ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options]; + + return $this; + } + public function addDateRange(string $name, ?string $label = null, ?DateTimeImmutable $from = null, ?DateTimeImmutable $to = null): self { $this->dateRanges[$name] = ['from' => $from, 'to' => $to, 'label' => $label]; @@ -75,6 +102,18 @@ class FilterOrderHelperBuilder $helper->addCheckbox($name, $choices, $default, $trans); } + foreach ( + $this->singleCheckboxes as $name => ['label' => $label] + ) { + $helper->addSingleCheckbox($name, $label); + } + + foreach ( + $this->entityChoices as $name => ['label' => $label, 'class' => $class, 'choices' => $choices, 'options' => $options] + ) { + $helper->addEntityChoice($name, $class, $label, $choices, $options); + } + foreach ( $this->dateRanges as $name => [ 'from' => $from, diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php b/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php index bc256e24f..b91cd86e8 100644 --- a/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php +++ b/src/Bundle/ChillMainBundle/Templating/Listing/Templating.php @@ -11,13 +11,23 @@ declare(strict_types=1); namespace Chill\MainBundle\Templating\Listing; +use Chill\MainBundle\Pagination\PaginatorFactory; +use Symfony\Component\HttpFoundation\RequestStack; use Twig\Environment; +use Twig\Error\LoaderError; +use Twig\Error\RuntimeError; +use Twig\Error\SyntaxError; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; class Templating extends AbstractExtension { - public function getFilters() + public function __construct( + private readonly RequestStack $requestStack, + ) { + } + + public function getFilters(): array { return [ new TwigFilter('chill_render_filter_order_helper', [$this, 'renderFilterOrderHelper'], [ @@ -26,16 +36,41 @@ class Templating extends AbstractExtension ]; } + /** + * @throws SyntaxError + * @throws RuntimeError + * @throws LoaderError + */ public function renderFilterOrderHelper( Environment $environment, FilterOrderHelper $helper, ?string $template = '@ChillMain/FilterOrder/base.html.twig', ?array $options = [] - ) { + ): string { + $otherParameters = []; + + foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) { + switch ($key) { + case FilterOrderHelper::FORM_NAME: + break; + + case PaginatorFactory::DEFAULT_CURRENT_PAGE_KEY: + // when filtering, go back to page 1 + $otherParameters[PaginatorFactory::DEFAULT_CURRENT_PAGE_KEY] = 1; + + break; + default: + $otherParameters[$key] = $value; + + break; + } + } + return $environment->render($template, [ 'helper' => $helper, 'form' => $helper->buildForm()->createView(), 'options' => $options, + 'otherParameters' => $otherParameters, ]); } }