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.

206 lines
7.8KB

  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(
  33. SessionInterface $session,
  34. EntityManagerInterface $entityManager,
  35. TranslatorAdmin $translatorAdmin
  36. ) {
  37. $this->session = $session;
  38. $this->em = $entityManager;
  39. $this->translatorAdmin = $translatorAdmin;
  40. }
  41. public function handleFiltersForm(
  42. RepositoryQueryInterface $repositoryQuery,
  43. Form $filtersForm,
  44. $fields,
  45. EntityDto $entityDto
  46. ): bool {
  47. foreach ($fields as $field) {
  48. $filteredValue = array();
  49. if ($field instanceof FieldInterface) {
  50. $fieldDto = $field->getAsDto();
  51. } else {
  52. $fieldDto = $field;
  53. }
  54. if ($fieldDto->isDisplayedOn(Crud::PAGE_INDEX)) {
  55. if ($filtersForm->has($this->getFieldPropertySnake($fieldDto->getProperty()))) {
  56. if ($fieldDto->getFormType() === DateTimeType::class || $fieldDto->getFormType(
  57. ) === DateType::class) {
  58. $filteredValue['dateStart'] = $this->getFilteredValue(
  59. $filtersForm,
  60. $entityDto->getFqcn(),
  61. $fieldDto->getProperty(),
  62. 'dateStart'
  63. );
  64. $filteredValue['dateEnd'] = $this->getFilteredValue(
  65. $filtersForm,
  66. $entityDto->getFqcn(),
  67. $fieldDto->getProperty(),
  68. 'dateEnd'
  69. );
  70. if ($filteredValue['dateStart'] || $filteredValue['dateEnd']) {
  71. $this->isFiltered = true;
  72. }
  73. } else {
  74. $filteredValue['value'] = $this->getFilteredValue(
  75. $filtersForm,
  76. $entityDto->getFqcn(),
  77. $fieldDto->getProperty()
  78. );
  79. if ($filteredValue['value']) {
  80. $this->isFiltered = true;
  81. }
  82. }
  83. $this->applyFilter($repositoryQuery, $fieldDto, $filteredValue);
  84. }
  85. }
  86. }
  87. return $this->isFiltered;
  88. }
  89. public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, array $filteredValue)
  90. {
  91. if ($fieldDto->getCustomOption('filter_fqcn')) {
  92. $filterFqcn = $fieldDto->getCustomOption('filter_fqcn');
  93. $customFilter = new $filterFqcn($this->translatorAdmin);
  94. $customFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  95. } else {
  96. switch ($fieldDto->getFormType()) {
  97. case CheckboxType::class:
  98. $checkboxFilter = new CheckboxFilter();
  99. $checkboxFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  100. break;
  101. case ChoiceType::class:
  102. $choiceFilter = new ChoiceFilter();
  103. $choiceFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  104. break;
  105. case IntegerType::class:
  106. $integerFilter = new IntegerFilter();
  107. $integerFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  108. break;
  109. case TextareaType::class:
  110. case TextType::class:
  111. case EmailType::class:
  112. $textFilter = new TextFilter();
  113. $textFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  114. break;
  115. case EntityType::class:
  116. $textFilter = new AssociationFilter();
  117. $textFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
  118. break;
  119. case DateTimeType::class:
  120. case DateType::class:
  121. $textFilter = new DateFilter();
  122. $textFilter->applyFilter(
  123. $repositoryQuery,
  124. $fieldDto,
  125. $filteredValue['dateStart'],
  126. $filteredValue['dateEnd']
  127. );
  128. break;
  129. }
  130. }
  131. }
  132. public function getFilteredValue(
  133. Form $filtersForm,
  134. string $entityFqcn,
  135. string $field,
  136. string $dateExtraField = null
  137. ) {
  138. $field = $this->getFieldPropertySnake($field);
  139. $sessionParam = "_filter/" . $entityFqcn . $field . $dateExtraField;
  140. $formField = $this->getFormField($filtersForm, $field, $dateExtraField);
  141. $value = $formField->getData();
  142. //Il existe une valeur posté dans le formulaire
  143. if ($value !== null) {
  144. $this->session->set($sessionParam, $value);
  145. return $value;
  146. }
  147. // pas de valeur et le form est envoyé, on supprimer le filtre correspondant
  148. elseif($formField->isSubmitted()) {
  149. $this->session->remove($sessionParam);
  150. }
  151. //action reset
  152. if ($filtersForm->get('reset')->getData() == 'clearAll') {
  153. $this->session->remove($sessionParam);
  154. return null;
  155. }
  156. //Récupération des valeurs stocké en sessions si le forrmFilters n'a pas été posté
  157. if ($this->session->get($sessionParam) && !$filtersForm->isSubmitted() && $formField) {
  158. $value = $this->session->get($sessionParam);
  159. //Champ date
  160. if ($formField->getConfig()->getOption('input') == 'datetime') {
  161. $filtersForm->get($field)->get($dateExtraField)->setData($value);
  162. //Champ association
  163. } elseif ($formField->getConfig()->getOption('class')) {
  164. $valFormated = $this->em->getRepository(
  165. $formField->getConfig()->getOption('class')
  166. )->find($value);
  167. $filtersForm->get($field)->setData($valFormated);
  168. } else {
  169. //Champ noramux
  170. $filtersForm->get($field)->setData($value);
  171. }
  172. return $value;
  173. }
  174. }
  175. public function getFormField(Form $filtersForm, string $field, string $extraField = null): Form
  176. {
  177. if ($extraField) {
  178. return $filtersForm->get($field)->get($extraField);
  179. } else {
  180. return $filtersForm->get($field);
  181. }
  182. }
  183. }