@@ -35,10 +35,12 @@ use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SeoInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SortableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusInterface; | |||
use Lc\SovBundle\Doctrine\Extension\TranslatableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\TreeInterface; | |||
use Lc\SovBundle\Field\CollectionField; | |||
use Lc\SovBundle\Field\GalleryManagerField; | |||
use Lc\SovBundle\Form\Type\Crud\IndexFilterType; | |||
use Lc\SovBundle\Form\Type\Crud\PositionType; | |||
use Symfony\Component\Form\Extension\Core\Type\CollectionType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
@@ -50,6 +52,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
{ | |||
protected $session; | |||
protected $request; | |||
protected $filtersForm; | |||
public function __construct(SessionInterface $session, RequestStack $request, EntityManager $em, Environment $twig) | |||
{ | |||
@@ -79,13 +82,13 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
Action::NEW => [ | |||
'icon' => 'plus', | |||
'label' => 'Créer', | |||
'add_class'=>'btn-sm' | |||
'add_class' => 'btn-sm', | |||
], | |||
Action::EDIT => [ | |||
'class' => 'btn btn-sm btn-primary', | |||
'icon' => 'edit', | |||
'label' => false, | |||
'html_attributes'=> array('data-toggle'=> 'tooltip', 'title'=> 'Éditer') | |||
'html_attributes' => array('data-toggle' => 'tooltip', 'title' => 'Éditer'), | |||
], | |||
Action::DELETE => [ | |||
'icon' => 'trash', | |||
@@ -146,7 +149,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$indexChildAction = Action::new('index_children', 'Afficher les enfants', 'fa fa-list') | |||
->linkToCrudAction(Action::INDEX) | |||
->setLabel('') | |||
->setHtmlAttributes(array('data-toggle'=> 'tooltip', 'title'=> 'Afficher les enfants')) | |||
->setHtmlAttributes(array('data-toggle' => 'tooltip', 'title' => 'Afficher les enfants')) | |||
->setTemplatePath('@LcSov/adminlte/crud/action/index_children.html.twig') | |||
->setCssClass('btn btn-sm btn-success'); | |||
@@ -190,7 +193,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
} | |||
if (isset($button['html_attributes']) && $button['html_attributes']) { | |||
$action->setHtmlAttributes( $button['html_attributes']); | |||
$action->setHtmlAttributes($button['html_attributes']); | |||
} | |||
return $action; | |||
@@ -206,6 +209,12 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
{ | |||
if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) { | |||
$responseParameters->set('fields', $this->configureFields('index')); | |||
if ($this->filtersForm === null) { | |||
$options['fields'] = $responseParameters->get('fields'); | |||
$this->filtersForm = $this->createForm(IndexFilterType::class, null, $options); | |||
} | |||
$responseParameters->set('filters_form', $this->filtersForm); | |||
} | |||
return $responseParameters; | |||
@@ -216,9 +225,10 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$crud = parent::configureCrud($crud); | |||
$this->setMaxResults($crud); | |||
if($this->isInstanceOf(SortableInterface::class)){ | |||
if ($this->isInstanceOf(SortableInterface::class)) { | |||
$crud->setDefaultSort(['position' => 'ASC']); | |||
} | |||
return $crud; | |||
} | |||
@@ -305,7 +315,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
->getForm(); | |||
$entityManager = $this->getDoctrine()->getManagerForClass($this->getEntityFqcn()); | |||
dump($entityManager); | |||
$repository = $entityManager->getRepository($this->getEntityFqcn()); | |||
$sortableForm->handleRequest($context->getRequest()); | |||
@@ -373,8 +383,6 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$fields, | |||
$filters | |||
); | |||
dump(get_defined_vars()); | |||
if ($this->isInstanceOf(TreeInterface::class)) { | |||
$entityId = $searchDto->getRequest()->get('entityId'); | |||
if ($entityId !== null) { | |||
@@ -384,7 +392,36 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$queryBuilder->andWhere('entity.parent IS NULL'); | |||
} | |||
} | |||
if ($this->isInstanceOf(StatusInterface::class)) { | |||
$queryBuilder->andWhere('entity.status >= 0'); | |||
} | |||
$fields = FieldCollection::new($this->configureFields(Crud::PAGE_INDEX)); | |||
$this->filtersForm = $this->createForm(IndexFilterType::class, null, array('fields' => $fields)); | |||
$this->filtersForm->handleRequest($searchDto->getRequest()); | |||
if (($this->filtersForm->isSubmitted() && $this->filtersForm->isValid())) { | |||
foreach ($fields as $field) { | |||
if ($field->isDisplayedOn(Crud::PAGE_INDEX)) { | |||
if ($this->filtersForm->has($field->getProperty())) { | |||
switch ($field->getFormType()) { | |||
case TextType::class: | |||
$filter = $this->filtersForm->get($field->getProperty())->getData(); | |||
//$filter = $this->filtersForm->get($field['property'])->getData(); | |||
if ($filter !== null) { | |||
$queryBuilder->andWhere( | |||
'entity.'.$field->getProperty().' LIKE :'.$field->getProperty().'' | |||
); | |||
$queryBuilder->setParameter($field->getProperty(), '%'.$filter.'%'); | |||
} | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
return $queryBuilder; | |||
} | |||
@@ -395,23 +432,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder { | |||
$queryBuilder = parent::createIndexQueryBuilder( | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
); | |||
if ($this->isInstanceOf(TreeInterface::class)) { | |||
$entityId = $searchDto->getRequest()->get('entityId'); | |||
if ($entityId !== null) { | |||
$queryBuilder->andWhere('entity.parent = :entityId'); | |||
$queryBuilder->setParameter('entityId', $searchDto->getRequest()->get('entityId')); | |||
} else { | |||
$queryBuilder->andWhere('entity.parent IS NULL'); | |||
} | |||
} | |||
$queryBuilder = $this->createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); | |||
return $queryBuilder; | |||
} | |||
@@ -434,5 +455,15 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$entityManager->flush(); | |||
} | |||
public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void | |||
{ | |||
if ($entityInstance instanceof StatusInterface) { | |||
$entityInstance->setStatus(-1); | |||
$entityManager->update($entityInstance); | |||
} else { | |||
$entityManager->remove($entityInstance); | |||
} | |||
$entityManager->flush(); | |||
} | |||
} | |||
@@ -0,0 +1,188 @@ | |||
<?php | |||
namespace Lc\SovBundle\Form\Type\Crud; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Doctrine\ORM\EntityRepository; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType; | |||
use Symfony\Component\Form\Extension\Core\Type\DateType; | |||
use Symfony\Component\Form\Extension\Core\Type\FormType; | |||
use Symfony\Component\Form\Extension\Core\Type\IntegerType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
use Symfony\Contracts\Translation\TranslatorInterface; | |||
class IndexFilterType extends AbstractType | |||
{ | |||
protected $em; | |||
protected $translator; | |||
protected $utils; | |||
public function __construct(EntityManagerInterface $entityManager, TranslatorInterface $translator) | |||
{ | |||
$this->em = $entityManager; | |||
$this->translator = $translator; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
foreach ($options['fields'] as $field) { | |||
if($field instanceof FieldInterface) { | |||
$fieldDto = $field->getAsDto(); | |||
}else{ | |||
$fieldDto = $field; | |||
} | |||
if ($fieldDto->isDisplayedOn(Crud::PAGE_INDEX)) { | |||
switch ($fieldDto->getFormType()) { | |||
case 'option': | |||
$refl = new \ReflectionClass($options['entity_class']); | |||
$choiceOptions = array(); | |||
foreach ($refl->getConstants() as $key => $value) { | |||
if (stripos($key, $this->utils->snakeCase($field['property'])) !== false) { | |||
$choiceOptions[$this->translator->trans( | |||
'field.'.$options['entity_name'].'.'.$field['property'].'Options.'.$value | |||
)] = $value; | |||
} | |||
} | |||
$builder->add( | |||
$field['property'], | |||
ChoiceType::class, | |||
array( | |||
'required' => false, | |||
'choices' => $choiceOptions, | |||
'attr' => array( | |||
'class' => 'select2 input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
break; | |||
case 'integer': | |||
$builder->add( | |||
$field['property'], | |||
TextType::class, | |||
array( | |||
'required' => false, | |||
'attr' => array( | |||
'class' => ' input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
break; | |||
case TextType::class: | |||
$builder->add( | |||
str_replace('.', '_', $fieldDto->getProperty()), | |||
TextType::class, | |||
array( | |||
'required' => false, | |||
'attr' => array( | |||
'class' => ' input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
break; | |||
case 'toggle': | |||
$builder->add( | |||
$field['property'], | |||
ChoiceType::class, | |||
array( | |||
'choices' => array( | |||
'Oui' => 1, | |||
'Non' => 0, | |||
), | |||
'placeholder' => '--', | |||
'required' => false, | |||
'attr' => array( | |||
'class' => 'select2 input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
break; | |||
case 'datetime': | |||
case 'date': | |||
$builder->add( | |||
$builder->create($field['property'], FormType::class, array('inherit_data' => true)) | |||
->add( | |||
'dateStart', | |||
DateType::class, | |||
array( | |||
'widget' => 'single_text', | |||
'required' => false, | |||
) | |||
) | |||
->add( | |||
'dateEnd', | |||
DateType::class, | |||
array( | |||
'widget' => 'single_text', | |||
'required' => false, | |||
) | |||
) | |||
); | |||
break; | |||
case 'association': | |||
$classImplements = class_implements($field['targetEntity']); | |||
$builder->add( | |||
$field['property'], | |||
EntityType::class, | |||
array( | |||
'class' => $field['targetEntity'], | |||
'placeholder' => '--', | |||
'query_builder' => function (EntityRepository $repo) use ($classImplements) { | |||
return $repo->createQueryBuilder('entity'); | |||
}, | |||
'required' => false, | |||
'attr' => array( | |||
'class' => 'select2 input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
break; | |||
case 'dateinterval': | |||
break; | |||
case 'float': | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
public function configureOptions(OptionsResolver $resolver) | |||
{ | |||
$resolver->setDefaults( | |||
[ | |||
'label' => false, | |||
'csrf_protection' => false, | |||
//'translation_domain' => 'lcshop', | |||
'fields' => false, | |||
'entity_name' => false, | |||
'entity_class' => false, | |||
//'entityClass' => false | |||
] | |||
); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
{% set filters_form_are_not_empty = false %} | |||
{% if filters_form is defined %} | |||
<tr class="table-filters-line"> | |||
{% if has_batch_actions %} | |||
<th></th> | |||
{% endif %} | |||
{% for field in fields ?? [] %} | |||
{% set field = field.getAsDto() %} | |||
{% if field.isDisplayedOn('index') %} | |||
<th> | |||
{% if filters_form[field.property] is defined %} | |||
{% set form_field = filters_form[field.property] %} | |||
{{ dump(field.property) }} | |||
{{ dump(form_field) }} | |||
{% if form_field.vars.value is not null and form_field.vars.value is not empty %}{% set filters_form_are_not_empty = true %}{% endif %} | |||
{# {% if metadata['dataType'] == 'datetime' or metadata['dataType'] == 'date' %} | |||
<div class="input-group input-group-sm"> | |||
<input type="text" | |||
class="form-control input-sm float-right date-range"> | |||
<div class="hidden date-time-range-fields" | |||
style="display: none;"> | |||
{{ form_widget(filters_form[field]['dateStart'], {"attr" : {'class' : 'date-start', 'form': 'filters-form'}}) }} | |||
{{ form_widget(filters_form[field]['dateEnd'], {"attr" : {'class' : 'date-end', 'form': 'filters-form'}}) }} | |||
</div> | |||
</div> | |||
{% else %} #} | |||
<div class="form-widget input-group-sm"> | |||
{# {% if metadata.dataType == 'integer' or metadata.dataType== 'string' or metadata.dataType== 'text' %} #} | |||
{# {{ form_widget(filters_form[field], {'attr': {'autocomplete': 'off', 'data-lc-autocomplete-url' : path('easyadmin', { | |||
action: 'autocomplete', | |||
field: field, | |||
entity: _entity_config.name, | |||
})|raw }}) }} #} | |||
{# {% else %} #} | |||
{{ form_widget(form_field) }} | |||
{# {% endif %} #} | |||
</div> | |||
{# {% endif %} #}{# | |||
#} | |||
{% endif %} | |||
{% endif %} | |||
</th> | |||
{% endfor %} | |||
{# {% if _list_item_actions|length > 0 %} #} | |||
<th class="actions"> | |||
<button type="submit" form="filters-form" class="btn btn-sm btn-info" | |||
data-toggle="tooltip" | |||
title="{{ "action.apply"|trans({}, 'lcshop') }}" | |||
aria-label="{{ "action.apply"|trans({}, 'lcshop') }}"> | |||
<i class="fa fa-search"></i> | |||
</button> | |||
</th> | |||
{# {% endif %} #} | |||
</tr> | |||
{% endif %} |
@@ -105,6 +105,9 @@ | |||
</th> | |||
</tr> | |||
{% endblock table_head %} | |||
{% block table_filters %} | |||
{{ include('@LcSov/adminlte/block/table_fitlers.html.twig') }} | |||
{% endblock table_filters %} | |||
</thead> | |||
<tbody> | |||
@@ -179,6 +182,21 @@ | |||
{% endblock table_body %} | |||
</tbody> | |||
</table> | |||
{% block filters_form %} | |||
{% if filters_form is defined %} | |||
{{ form_start(filters_form, {'attr' :{'id' : 'filters-form'}}) }} | |||
{#<input type="hidden" name="entity" value="{{ _entity_config.name }}"> | |||
<input type="hidden" name="menuIndex" value="{{ app.request.get('menuIndex') }}"> | |||
<input type="hidden" name="submenuIndex" value="{{ app.request.get('submenuIndex') }}"> | |||
<input type="hidden" name="sortField" value="{{ app.request.get('sortField', '') }}"> | |||
<input type="hidden" name="sortDirection" | |||
value="{{ app.request.get('sortDirection', 'DESC') }}"> | |||
<input type="hidden" name="action" value="{{ app.request.get('action') }}">#} | |||
{{ form_end(filters_form) }} | |||
{% endif %} | |||
{% endblock filters_form %} | |||
</div> | |||
{% endblock %} | |||
{% block footer %} |