You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
7.5KB

  1. <?php
  2. namespace Lc\SovBundle\Field\Filter;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use DoctrineExtensions\Query\Mysql\Field;
  5. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  6. use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
  7. use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
  8. use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
  9. use Lc\SovBundle\Repository\RepositoryQueryInterface;
  10. use Lc\SovBundle\Translation\TranslatorAdmin;
  11. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  12. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  13. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  14. use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
  15. use Symfony\Component\Form\Extension\Core\Type\DateType;
  16. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  17. use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  18. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  19. use Symfony\Component\Form\Extension\Core\Type\TextType;
  20. use Symfony\Component\Form\Form;
  21. use Symfony\Component\HttpFoundation\RequestStack;
  22. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  23. /**
  24. * @author La clic ! <contact@laclic.fr>
  25. */
  26. class FilterManager
  27. {
  28. protected $em;
  29. protected bool $isFiltered = false;
  30. protected $translatorAdmin;
  31. use FilterTrait;
  32. public function __construct(SessionInterface $session, EntityManagerInterface $entityManager, TranslatorAdmin $translatorAdmin)
  33. {
  34. $this->session = $session;
  35. $this->em = $entityManager;
  36. $this->translatorAdmin = $translatorAdmin;
  37. }
  38. public function handleFiltersForm(RepositoryQueryInterface $repositoryQuery, Form $filtersForm, $fields, EntityDto $entityDto):bool
  39. {
  40. foreach ($fields as $field) {
  41. $filteredValue = array();
  42. if ($field instanceof FieldInterface) {
  43. $fieldDto = $field->getAsDto();
  44. } else {
  45. $fieldDto = $field;
  46. }
  47. if ($fieldDto->isDisplayedOn(Crud::PAGE_INDEX)) {
  48. if ($filtersForm->has($this->getFieldPropertySnake($fieldDto->getProperty()))) {
  49. if ($fieldDto->getFormType() === DateTimeType::class || $fieldDto->getFormType() === DateType::class) {
  50. $filteredValue['dateStart'] = $this->getFilteredValue(
  51. $filtersForm,
  52. $entityDto->getFqcn(),
  53. $fieldDto->getProperty(),
  54. 'dateStart'
  55. );
  56. $filteredValue['dateEnd'] = $this->getFilteredValue(
  57. $filtersForm,
  58. $entityDto->getFqcn(),
  59. $fieldDto->getProperty(),
  60. 'dateEnd'
  61. );
  62. if($filteredValue['dateStart'] || $filteredValue['dateEnd']){
  63. $this->isFiltered = true;
  64. }
  65. } else {
  66. $filteredValue['value'] = $this->getFilteredValue(
  67. $filtersForm,
  68. $entityDto->getFqcn(),
  69. $fieldDto->getProperty()
  70. );
  71. if($filteredValue['value'] ){
  72. $this->isFiltered = true;
  73. }
  74. }
  75. $this->applyFilter($repositoryQuery, $fieldDto, $filteredValue);
  76. }
  77. }
  78. }
  79. return $this->isFiltered;
  80. }
  81. public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, array $filteredValue)
  82. {
  83. if ($fieldDto->getCustomOption('filter_fqcn')) {
  84. $filterFqcn = $fieldDto->getCustomOption('filter_fqcn');
  85. $customFilter = new $filterFqcn($this->translatorAdmin);
  86. $customFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  87. } else {
  88. switch ($fieldDto->getFormType()) {
  89. case CheckboxType::class:
  90. $checkboxFilter = new CheckboxFilter();
  91. $checkboxFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  92. break;
  93. case ChoiceType::class:
  94. $choiceFilter = new ChoiceFilter();
  95. $choiceFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  96. break;
  97. case IntegerType::class:
  98. $integerFilter = new IntegerFilter();
  99. $integerFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  100. break;
  101. case TextareaType::class:
  102. case TextType::class:
  103. case EmailType::class:
  104. $textFilter = new TextFilter();
  105. $textFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  106. break;
  107. case EntityType::class:
  108. $textFilter = new AssociationFilter();
  109. $textFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  110. break;
  111. case DateTimeType::class:
  112. case DateType::class:
  113. $textFilter = new DateFilter();
  114. $textFilter->applyFilter(
  115. $repositoryQuery,
  116. $fieldDto,
  117. $filteredValue['dateStart'],
  118. $filteredValue['dateEnd']
  119. );
  120. break;
  121. }
  122. }
  123. }
  124. public function getFilteredValue(
  125. Form $filtersForm,
  126. string $entityFqcn,
  127. string $field,
  128. string $dateExtraField = null
  129. )
  130. {
  131. $field = $this->getFieldPropertySnake($field);
  132. $sessionParam = $entityFqcn . $field . $dateExtraField;
  133. $formField = $this->getFormField($filtersForm, $field, $dateExtraField);
  134. $value = $formField->getData();
  135. //Il existe une valeur posté dans le formulaire
  136. if ($value !== null) {
  137. $this->session->set($sessionParam, $value);
  138. return $value;
  139. }
  140. //action reset
  141. if ($filtersForm->get('reset')->getData() == 'clearAll') {
  142. $this->session->remove($sessionParam);
  143. return null;
  144. }
  145. //Récupération des valeurs stocké en sessions si le forrmFilters n'a pas été posté
  146. if ($this->session->get($sessionParam) && !$filtersForm->isSubmitted() && $formField) {
  147. $value = $this->session->get($sessionParam);
  148. //Champ date
  149. if ($formField->getConfig()->getOption('input') == 'datetime') {
  150. $filtersForm->get($field)->get($dateExtraField)->setData($value);
  151. //Champ association
  152. } elseif ($formField->getConfig()->getOption('class')) {
  153. $valFormated = $this->em->getRepository(
  154. $formField->getConfig()->getOption('class')
  155. )->find($value);
  156. $filtersForm->get($field)->setData($valFormated);
  157. } else {
  158. //Champ noramux
  159. $filtersForm->get($field)->setData($value);
  160. }
  161. return $value;
  162. }
  163. }
  164. public function getFormField(Form $filtersForm, string $field, string $extraField = null): Form
  165. {
  166. if ($extraField) {
  167. return $filtersForm->get($field)->get($extraField);
  168. } else {
  169. return $filtersForm->get($field);
  170. }
  171. }
  172. }