add possibility to generate filter/order elements, with only search box

for now
This commit is contained in:
2021-10-08 16:50:31 +02:00
parent e286acf9fe
commit 4d71a1c630
15 changed files with 325 additions and 89 deletions

View File

@@ -20,6 +20,8 @@
namespace Chill\MainBundle\CRUD\Controller;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
@@ -251,7 +253,8 @@ class CRUDController extends AbstractController
return $response;
}
$totalItems = $this->countEntities($action, $request);
$filterOrder = $this->buildFilterOrderHelper($action, $request);
$totalItems = $this->countEntities($action, $request, $filterOrder);
$paginator = $this->getPaginatorFactory()->create($totalItems);
$response = $this->onPreIndexBuildQuery($action, $request, $totalItems,
@@ -261,7 +264,7 @@ class CRUDController extends AbstractController
return $response;
}
$entities = $this->getQueryResult($action, $request, $totalItems, $paginator);
$entities = $this->getQueryResult($action, $request, $totalItems, $paginator, $filterOrder);
$response = $this->onPostIndexFetchQuery($action, $request, $totalItems,
$paginator, $entities);
@@ -273,7 +276,8 @@ class CRUDController extends AbstractController
$defaultTemplateParameters = [
'entities' => $entities,
'crud_name' => $this->getCrudName(),
'paginator' => $paginator
'paginator' => $paginator,
'filter_order' => $filterOrder
];
return $this->render(
@@ -282,6 +286,11 @@ class CRUDController extends AbstractController
);
}
protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper
{
return null;
}
/**
* @param string $action
* @param Request $request
@@ -354,9 +363,9 @@ class CRUDController extends AbstractController
* @param PaginatorInterface $paginator
* @return type
*/
protected function queryEntities(string $action, Request $request, PaginatorInterface $paginator)
protected function queryEntities(string $action, Request $request, PaginatorInterface $paginator, ?FilterOrderHelper $filterOrder = null)
{
$query = $this->buildQueryEntities($action, $request)
$query = $this->buildQueryEntities($action, $request, $filterOrder)
->setFirstResult($paginator->getCurrentPage()->getFirstItemNumber())
->setMaxResults($paginator->getItemsPerPage());
@@ -388,9 +397,10 @@ class CRUDController extends AbstractController
* @param PaginatorInterface $paginator
* @return mixed
*/
protected function getQueryResult(string $action, Request $request, int $totalItems, PaginatorInterface $paginator)
protected function getQueryResult(string $action, Request $request, int $totalItems, PaginatorInterface $paginator,
?FilterOrderHelper $filterOrder = null)
{
$query = $this->queryEntities($action, $request, $paginator);
$query = $this->queryEntities($action, $request, $paginator, $filterOrder);
return $query->getQuery()->getResult();
}
@@ -402,9 +412,9 @@ class CRUDController extends AbstractController
* @param Request $request
* @return int
*/
protected function countEntities(string $action, Request $request): int
protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int
{
return $this->buildQueryEntities($action, $request)
return $this->buildQueryEntities($action, $request, $filterOrder)
->select('COUNT(e)')
->getQuery()
->getSingleScalarResult()
@@ -1177,6 +1187,11 @@ class CRUDController extends AbstractController
return $this->get(Resolver::class);
}
protected function getFilterOrderHelperFactory(): FilterOrderHelperFactoryInterface
{
return $this->get(FilterOrderHelperFactoryInterface::class);
}
/**
* @return array
*/
@@ -1191,6 +1206,7 @@ class CRUDController extends AbstractController
EventDispatcherInterface::class => EventDispatcherInterface::class,
Resolver::class => Resolver::class,
SerializerInterface::class => SerializerInterface::class,
FilterOrderHelperFactoryInterface::class => FilterOrderHelperFactoryInterface::class,
]
);
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Chill\MainBundle\Form\Type\Listing;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SearchType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\RequestStack;
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 */
$helper = $options['helper'];
if ($helper->hasSearchBox()) {
$builder->add('q', SearchType::class, [
'label' => false,
'required' => false
]);
}
foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) {
switch($key) {
case 'q':
continue;
case 'page':
$builder->add($key, HiddenType::class, [
'data' => 1
]);
break;
default:
$builder->add($key, HiddenType::class, [
'data' => $value
]);
break;
}
}
}
public function configureOptions(\Symfony\Component\OptionsResolver\OptionsResolver $resolver)
{
$resolver->setRequired('helper')
->setAllowedTypes('helper', FilterOrderHelper::class);
}
}

View File

@@ -4,6 +4,12 @@
<h1>{{ ('crud.' ~ crud_name ~ '.index.title')|trans({'%crud_name%': crud_name}) }}</h1>
{% endblock index_header %}
{% block filter_order %}
{% if filter_order is not null %}
{{ filter_order|chill_render_filter_order_helper }}
{% endif %}
{% endblock %}
{% if entities|length == 0 %}
{% block no_existing_entities %}
<p>{{ no_existing_entities_sentences|default('No entities')|trans }}</p>

View File

@@ -0,0 +1,12 @@
{{ form_start(form) }}
<div class="chill_filter_order container">
<div class="row">
<div class="col-md-12">
<div class="input-group mb-3">
{{ form_widget(form.q)}}
<button type="submit" class="btn btn-chill-l-gray"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
</div>
{{ form_end(form) }}

View File

@@ -0,0 +1,60 @@
<?php
namespace Chill\MainBundle\Templating\Listing;
use Chill\MainBundle\Form\Type\Listing\FilterOrderType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class FilterOrderHelper
{
private FormFactoryInterface $formFactory;
private RequestStack $requestStack;
private ?array $searchBoxFields = null;
public function __construct(
FormFactoryInterface $formFactory,
RequestStack $requestStack
) {
$this->formFactory = $formFactory;
$this->requestStack = $requestStack;
}
public function setSearchBox($searchBoxFields = null): self
{
$this->searchBoxFields = $searchBoxFields;
return $this;
}
public function hasSearchBox(): bool
{
return $this->searchBoxFields !== null;
}
private function getFormData(): array
{
return [
'q' => $this->getQueryString()
];
}
public function getQueryString(): ?string
{
$q = $this->requestStack->getCurrentRequest()
->query->get('q', null);
return empty($q) ? NULL : $q;
}
public function buildForm($name = null, string $type = FilterOrderType::class, array $options = []): FormInterface
{
return $this->formFactory
->createNamed($name, $type, $this->getFormData(), \array_merge([
'helper' => $this,
'method' => 'GET',
'csrf_protection' => false,
], $options));
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Chill\MainBundle\Templating\Listing;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class FilterOrderHelperBuilder
{
private ?array $searchBoxFields = null;
private FormFactoryInterface $formFactory;
private RequestStack $requestStack;
public function __construct(
FormFactoryInterface $formFactory,
RequestStack $requestStack
) {
$this->formFactory = $formFactory;
$this->requestStack = $requestStack;
}
public function addSearchBox(array $fields, ?array $options = []): self
{
$this->searchBoxFields = $fields;
return $this;
}
public function build(): FilterOrderHelper
{
$helper = new FilterOrderHelper(
$this->formFactory,
$this->requestStack
);
$helper->setSearchBox($this->searchBoxFields);
return $helper;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Chill\MainBundle\Templating\Listing;
use Symfony\Component\Form\FormFactoryBuilderInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class FilterOrderHelperFactory implements FilterOrderHelperFactoryInterface
{
private FormFactoryInterface $formFactory;
private RequestStack $requestStack;
public function __construct(
FormFactoryInterface $formFactory,
RequestStack $requestStack
) {
$this->formFactory = $formFactory;
$this->requestStack = $requestStack;
}
public function create(string $context, ?array $options = []): FilterOrderHelperBuilder
{
return new FilterOrderHelperBuilder($this->formFactory, $this->requestStack);
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Chill\MainBundle\Templating\Listing;
interface FilterOrderHelperFactoryInterface
{
public function create(string $context, ?array $options = []): FilterOrderHelperBuilder;
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Chill\MainBundle\Templating\Listing;
use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class Templating extends AbstractExtension
{
public function getFilters()
{
return [
new TwigFilter('chill_render_filter_order_helper', [$this, 'renderFilterOrderHelper'], [
'needs_environment' => true, 'is_safe' => ['html'],
])
];
}
public function renderFilterOrderHelper(
Environment $environment,
FilterOrderHelper $helper,
?string $template = '@ChillMain/FilterOrder/base.html.twig',
?array $options = []
) {
return $environment->render($template, [
'helper' => $helper,
'form' => $helper->buildForm()->createView(),
'options' => $options
]);
}
}

View File

@@ -36,7 +36,7 @@ services:
autowire: true
tags:
- { name: 'chill.render_entity' }
Chill\MainBundle\Templating\ChillMarkdownRenderExtension:
tags:
- { name: twig.extension }
@@ -46,4 +46,10 @@ services:
- '@Symfony\Component\Templating\EngineInterface'
tags:
- { name: 'chill.render_entity' }
Chill\MainBundle\Templating\Listing\:
resource: './../../Templating/Listing'
autoconfigure: true
autowire: true
Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface: '@Chill\MainBundle\Templating\Listing\FilterOrderHelperFactory'