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.6KB

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