No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

778 líneas
30KB

  1. <?php
  2. namespace Lc\SovBundle\Controller;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Doctrine\ORM\QueryBuilder;
  5. use EasyCorp\Bundle\EasyAdminBundle\Collection\ActionCollection;
  6. use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection;
  7. use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
  8. use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
  9. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  10. use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
  11. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  12. use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
  13. use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA;
  14. use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
  15. use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface;
  16. use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController as EaAbstractCrudController;
  17. use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
  18. use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
  19. use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
  20. use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent;
  21. use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent;
  22. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent;
  23. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;
  24. use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException;
  25. use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException;
  26. use EasyCorp\Bundle\EasyAdminBundle\Factory\ControllerFactory;
  27. use EasyCorp\Bundle\EasyAdminBundle\Factory\EntityFactory;
  28. use EasyCorp\Bundle\EasyAdminBundle\Factory\FilterFactory;
  29. use EasyCorp\Bundle\EasyAdminBundle\Factory\PaginatorFactory;
  30. use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
  31. use EasyCorp\Bundle\EasyAdminBundle\Field\FormField;
  32. use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
  33. use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
  34. use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider;
  35. use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
  36. use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
  37. use Lc\SovBundle\Component\EntityComponent;
  38. use Lc\SovBundle\Definition\ActionDefinition;
  39. use Lc\SovBundle\Doctrine\Extension\DevAliasInterface;
  40. use Lc\SovBundle\Doctrine\Extension\SeoInterface;
  41. use Lc\SovBundle\Doctrine\Extension\SortableInterface;
  42. use Lc\SovBundle\Doctrine\Extension\TranslatableInterface;
  43. use Lc\SovBundle\Doctrine\Extension\TreeInterface;
  44. use Lc\SovBundle\Field\CollectionField;
  45. use Lc\SovBundle\Field\Filter\FilterManager;
  46. use Lc\SovBundle\Form\Common\FiltersFormType;
  47. use Lc\SovBundle\Form\Common\PositionType;
  48. use Lc\SovBundle\Repository\EntityRepository;
  49. use Lc\SovBundle\Repository\RepositoryQueryInterface;
  50. use Lc\SovBundle\Translation\FlashBagTranslator;
  51. use Lc\SovBundle\Translation\TranslatorAdmin;
  52. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  53. use Symfony\Component\Form\Extension\Core\Type\TextType;
  54. use Symfony\Component\Form\FormInterface;
  55. use Symfony\Component\HttpFoundation\JsonResponse;
  56. use Symfony\Component\HttpFoundation\RequestStack;
  57. abstract class AbstractAdminController extends EaAbstractCrudController
  58. {
  59. use ControllerTrait;
  60. protected FormInterface $filtersForm;
  61. abstract public function getRepositoryQuery(): RepositoryQueryInterface;
  62. public function configureResponseParameters(KeyValueStore $responseParameters): KeyValueStore
  63. {
  64. if ($responseParameters->get('global_actions')) {
  65. $this->overrideGlobalActions($responseParameters->get('global_actions'));
  66. }
  67. if ($responseParameters->get('entities')) {
  68. $this->overrideEntitiesActions($responseParameters->get('entities'));
  69. }
  70. if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) {
  71. $responseParameters->set('fields', $this->configureFields('index'));
  72. //TODO supprimer ce code rapport au filtre dans les index
  73. /*if ($this->filtersForm === null) {
  74. die('nncncd');
  75. $options['fields'] = $responseParameters->get('fields');
  76. $options['entity_class'] = $this->getEntityFqcn();
  77. $options['entity_name'] = $responseParameters->get('entity')->getName();
  78. $this->filtersForm = $this->createForm(FiltersFormType::class, null, $options);
  79. }*/
  80. $responseParameters->set('filters_form', $this->filtersForm);
  81. }
  82. $responseParameters->set('translation_entity_name', $this->getTranslationEntityName());
  83. return $responseParameters;
  84. }
  85. public function getTranslationEntityName()
  86. {
  87. return $this->getEntityFqcn();
  88. }
  89. public function overrideEntitiesActions(?EntityCollection $entities): void
  90. {
  91. }
  92. public function overrideGlobalActions(?ActionCollection $actions): void
  93. {
  94. if ($actions) {
  95. $context = $this->get(AdminContextProvider::class)->getContext();
  96. $adminUrlGenerator = $this->get(AdminUrlGenerator::class);
  97. foreach ($actions as $i => $action) {
  98. //récriture du bouton 'retour au parent'
  99. if ($action->getName() == 'index_parent') {
  100. $entity = $context->getEntity()->getInstance();
  101. if ($entity !== null) {
  102. if ($entity->getParent() !== null) {
  103. $url = $adminUrlGenerator
  104. ->setController($context->getCrud()->getControllerFqcn())
  105. ->set('entityId', $entity->getParent()->getId())
  106. ->generateUrl();
  107. $action->setLinkUrl($url);
  108. }
  109. } else {
  110. unset($actions[$i]);
  111. }
  112. }
  113. if ($action->getName() == 'sort') {
  114. $entityId = $context->getRequest()->get('entityId');
  115. if ($entityId != null) {
  116. $url = $adminUrlGenerator
  117. ->setController($context->getCrud()->getControllerFqcn())
  118. ->setAction($action->getName())
  119. ->set('entityId', $entityId)
  120. ->generateUrl();
  121. $action->setLinkUrl($url);
  122. }
  123. }
  124. }
  125. }
  126. }
  127. public function configureCrud(Crud $crud): Crud
  128. {
  129. $crud = parent::configureCrud($crud);
  130. $this->setMaxResults($crud);
  131. $crud->setFormOptions(['translation_entity_name' => $this->getTranslationEntityName()]);
  132. if ($this->isInstanceOf(SortableInterface::class)) {
  133. $crud->setDefaultSort(['position' => 'ASC']);
  134. }
  135. return $crud;
  136. }
  137. public function setMaxResults(Crud $crud): void
  138. {
  139. $entityClass = $this->getEntityFqcn();
  140. $paramListMaxResults = 'listMaxResults';
  141. $paramSessionListMaxResults = $entityClass . '-' . $paramListMaxResults;
  142. $requestListMaxResults = $this->get(RequestStack::class)->getCurrentRequest()->get($paramListMaxResults);
  143. if ($requestListMaxResults) {
  144. $this->get('session')->set($paramSessionListMaxResults, $requestListMaxResults);
  145. }
  146. $maxResults = $this->get('session')->get($paramSessionListMaxResults) ? $this->get('session')->get(
  147. $paramSessionListMaxResults
  148. ) : 30;
  149. $crud->setPaginatorPageSize($maxResults);
  150. }
  151. public function getSeoPanel(): ?array
  152. {
  153. if ($this->isInstanceOf(SeoInterface::class)) {
  154. return [
  155. FormField::addPanel('seo')->setTemplateName('crud/field/generic'),
  156. TextField::new('metaTitle')->setLabel('Meta Title')->setHelp(
  157. 'Affiché dans les résultats de recherche Google'
  158. )->hideOnIndex(),
  159. TextareaField::new('metaDescription')->setLabel('Meta description')->setHelp(
  160. 'Affiché dans les résultats de recherche Google'
  161. )->hideOnIndex(),
  162. CollectionField::new('oldUrls')
  163. ->setFormTypeOption('entry_type', TextType::class)->setLabel(
  164. 'Anciennes urls du document'
  165. )->hideOnIndex(),
  166. ];
  167. } else {
  168. return null;
  169. }
  170. }
  171. public function getConfPanel(): ?array
  172. {
  173. if ($this->isInstanceOf(DevAliasInterface::class)) {
  174. return [
  175. FormField::addPanel('configuration')->setTemplateName('crud/field/generic'),
  176. TextField::new('devAlias')->hideOnIndex(),
  177. ];
  178. } else {
  179. return null;
  180. }
  181. }
  182. public function sort(AdminContext $context)
  183. {
  184. $event = new BeforeCrudActionEvent($context);
  185. $this->get('event_dispatcher')->dispatch($event);
  186. if ($event->isPropagationStopped()) {
  187. return $event->getResponse();
  188. }
  189. //if (!$this->isGranted(Permission::EA_EXECUTE_ACTION) || !$this->isInstanceOf(SortableInterface::class)) {
  190. if (!$this->isInstanceOf(SortableInterface::class)) {
  191. throw new ForbiddenActionException($context);
  192. }
  193. $fields = FieldCollection::new($this->configureFields(Crud::PAGE_INDEX));
  194. $filters = $this->get(FilterFactory::class)->create(
  195. $context->getCrud()->getFiltersConfig(),
  196. $fields,
  197. $context->getEntity()
  198. );
  199. $queryBuilder = $this->createIndexQueryBuilder($context->getSearch(), $context->getEntity(), $fields, $filters);
  200. $paginator = $this->get(PaginatorFactory::class)->create($queryBuilder);
  201. $entities = $this->get(EntityFactory::class)->createCollection($context->getEntity(), $paginator->getResults());
  202. $this->get(EntityFactory::class)->processFieldsForAll($entities, $fields);
  203. $sortableForm = $this->createFormBuilder(array('entities', $paginator->getResults()))
  204. ->add(
  205. 'entities',
  206. CollectionType::class,
  207. array(
  208. 'required' => true,
  209. 'allow_add' => true,
  210. 'entry_type' => PositionType::class,
  211. )
  212. )
  213. ->getForm();
  214. $entityManager = $this->getDoctrine()->getManagerForClass($this->getEntityFqcn());
  215. $repository = $entityManager->getRepository($this->getEntityFqcn());
  216. $sortableForm->handleRequest($context->getRequest());
  217. if ($sortableForm->isSubmitted() && $sortableForm->isValid()) {
  218. foreach ($sortableForm->get('entities')->getData() as $elm) {
  219. $entityInstance = $repository->find($elm['id']);
  220. $entityDto = $context->getEntity()->newWithInstance($entityInstance);
  221. if (!$entityDto->isAccessible()) {
  222. throw new InsufficientEntityPermissionException($context);
  223. }
  224. $event = new BeforeEntityDeletedEvent($entityInstance);
  225. $this->get('event_dispatcher')->dispatch($event);
  226. $entityInstance = $event->getEntityInstance();
  227. $entityInstance->setPosition($elm['position']);
  228. $this->updateEntity($entityManager, $entityInstance);
  229. $this->get('event_dispatcher')->dispatch(new AfterEntityUpdatedEvent($entityInstance));
  230. }
  231. $url = $this->get(AdminUrlGenerator::class)
  232. ->setAction(ActionDefinition::INDEX)
  233. ->generateUrl();
  234. $this->addFlashTranslator('success', 'sorted');
  235. return $this->redirect($url);
  236. }
  237. $responseParameters = $this->configureResponseParameters(
  238. KeyValueStore::new(
  239. [
  240. 'pageName' => Crud::PAGE_INDEX,
  241. 'templatePath' => '@LcSov/adminlte/crud/sort.html.twig',
  242. 'entities' => $entities,
  243. 'paginator' => $paginator,
  244. 'global_actions' => array(),
  245. 'batch_actions' => array(),
  246. 'filters' => $filters,
  247. 'sortable_form' => $sortableForm,
  248. ]
  249. )
  250. );
  251. $responseParameters->set('fields', $this->configureFields('index'));
  252. $event = new AfterCrudActionEvent($context, $responseParameters);
  253. $this->get('event_dispatcher')->dispatch($event);
  254. if ($event->isPropagationStopped()) {
  255. return $event->getResponse();
  256. }
  257. return $responseParameters;
  258. }
  259. public function duplicate(
  260. AdminContext $context,
  261. EntityComponent $entityComponent,
  262. TranslatorAdmin $translatorAdmin,
  263. EntityManagerInterface $em
  264. ) {
  265. if (!$this->isGranted(
  266. Permission::EA_EXECUTE_ACTION,
  267. ['action' => "duplicate", 'entity' => $context->getEntity()]
  268. )) {
  269. throw new ForbiddenActionException($context);
  270. }
  271. if (!$context->getEntity()->isAccessible()) {
  272. throw new InsufficientEntityPermissionException($context);
  273. }
  274. $newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance());
  275. $em->create($newEntity);
  276. $em->flush();
  277. $url = $this->get(AdminUrlGenerator::class)
  278. ->setAction(ActionDefinition::EDIT)
  279. ->setEntityId($newEntity->getId())
  280. ->generateUrl();
  281. $this->addFlashTranslator('success', 'duplicated');
  282. return $this->redirect($url);
  283. }
  284. public function createIndexRepositoryQuery(
  285. SearchDto $searchDto,
  286. EntityDto $entityDto,
  287. FieldCollection $fields,
  288. FilterCollection $filters
  289. ): RepositoryQueryInterface
  290. {
  291. $repositoryQuery = $this->get(EntityRepository::class)->createRepositoryQuery($this->getRepositoryQuery(), $searchDto, $entityDto, $fields, $filters);
  292. // TODO : déplacer dans EntotyRepository
  293. if ($this->isInstanceOf(TreeInterface::class)) {
  294. if ($entityDto->getInstance()) {
  295. $repositoryQuery->filterByParent($entityDto->getInstance());
  296. } else {
  297. $repositoryQuery->filterIsParent();
  298. }
  299. }
  300. $this->filtersForm = $this->createForm(
  301. FiltersFormType::class,
  302. null,
  303. array(
  304. 'fields' => $fields,
  305. 'entity_dto' => $entityDto,
  306. 'entity_class' => $this->getEntityFqcn(),
  307. 'entity_name' => $entityDto->getName(),
  308. )
  309. );
  310. $filterManager = $this->get(FilterManager::class);
  311. $this->filtersForm->handleRequest($searchDto->getRequest());
  312. $filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto);
  313. return $repositoryQuery;
  314. }
  315. public function createIndexQueryBuilder(
  316. SearchDto $searchDto,
  317. EntityDto $entityDto,
  318. FieldCollection $fields,
  319. FilterCollection $filters
  320. ): QueryBuilder {
  321. $repositoryQuery = $this->createIndexRepositoryQuery($searchDto, $entityDto, $fields, $filters);
  322. return $repositoryQuery->getQueryBuilder();
  323. }
  324. public function createSortQueryBuilder(
  325. SearchDto $searchDto,
  326. EntityDto $entityDto,
  327. FieldCollection $fields,
  328. FilterCollection $filters
  329. ): QueryBuilder {
  330. $queryBuilder = $this->createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
  331. return $queryBuilder;
  332. }
  333. public function edit(AdminContext $context)
  334. {
  335. $response = parent::edit($context);;
  336. // on vide le flash bag si édition en ajax (notification déjà affichée en Javascript)
  337. if ($context->getRequest()->isXmlHttpRequest()) {
  338. $this->get('session')->getFlashBag()->clear();
  339. }
  340. return $response;
  341. }
  342. public function getControllerFqcnByInterface(string $interface): string
  343. {
  344. $context = $this->get(AdminContextProvider::class)->getContext();
  345. return $context->getCrudControllers()->findCrudFqcnByEntityFqcn(
  346. $this->get(EntityManagerInterface::class)->getEntityName($interface)
  347. );
  348. }
  349. public function updateEntity(EntityManagerInterface $entityManager, $entityInstance): void
  350. {
  351. $entityManager->update($entityInstance);
  352. $entityManager->flush();
  353. $this->get(FlashBagTranslator::class)->add('success', 'updated', $this->getTranslationEntityName());
  354. }
  355. public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
  356. {
  357. $entityManager->create($entityInstance);
  358. $entityManager->flush();
  359. $this->get(FlashBagTranslator::class)->add('success', 'created', $this->getTranslationEntityName());
  360. }
  361. public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void
  362. {
  363. $entityManager->delete($entityInstance);
  364. $entityManager->flush();
  365. $this->get(FlashBagTranslator::class)->add('success', 'deleted', $this->getTranslationEntityName());
  366. }
  367. public function configureActions(Actions $actions): Actions
  368. {
  369. $this->buildIndexActions($actions);
  370. $this->buildEditActions($actions);
  371. $this->buildDetailActions($actions);
  372. $this->buildNewActions($actions);
  373. $this->handleTranslatableEntityActions($actions);
  374. $this->handleSortableEntityActions($actions);
  375. $this->handleTreeEntityActions($actions);
  376. /*$actions->reorder(Crud::PAGE_EDIT, [ActionDefinition::INDEX, ActionDefinition::SAVE_AND_RETURN, ActionDefinition::SAVE_AND_CONTINUE, ActionDefinition::DELETE]);
  377. $actions->reorder(Crud::PAGE_NEW, [ActionDefinition::INDEX, ActionDefinition::SAVE_AND_RETURN, ActionDefinition::SAVE_AND_ADD_ANOTHER]);*/
  378. return $actions;
  379. }
  380. public function getDuplicateAction(): Action
  381. {
  382. $duplicateAction = Action::new(
  383. ActionDefinition::DUPLICATE,
  384. $this->get(TranslatorAdmin::class)->transAction(ActionDefinition::DUPLICATE),
  385. 'fa fa-fw fa-copy'
  386. )
  387. ->linkToCrudAction(ActionDefinition::DUPLICATE)
  388. ->setLabel($this->get(TranslatorAdmin::class)->transAction(ActionDefinition::DUPLICATE))
  389. ->setCssClass('in-dropdown text-info action-confirm');
  390. return $duplicateAction;
  391. }
  392. public function buildIndexActions(Actions $actions): void
  393. {
  394. $actions->add(Crud::PAGE_INDEX, $this->getDuplicateAction());
  395. $this->actionUpdate(
  396. $actions,
  397. Crud::PAGE_INDEX,
  398. ActionDefinition::NEW,
  399. [
  400. 'icon' => 'plus',
  401. 'label' => $this->get(TranslatorAdmin::class)->transAction('create'),
  402. 'add_class' => 'btn-sm',
  403. ]
  404. );
  405. $this->actionUpdate(
  406. $actions,
  407. Crud::PAGE_INDEX,
  408. ActionDefinition::EDIT,
  409. [
  410. 'class' => 'btn btn-sm btn-primary',
  411. 'icon' => 'edit',
  412. 'label' => false,
  413. 'html_attributes' => array(
  414. 'data-toggle' => 'tooltip',
  415. 'title' => $this->get(TranslatorAdmin::class)->transAction('edit'),
  416. ),
  417. ]
  418. );
  419. $this->actionUpdate(
  420. $actions,
  421. Crud::PAGE_INDEX,
  422. ActionDefinition::DETAIL,
  423. [
  424. 'icon' => 'eye',
  425. 'add_class' => 'btn btn-sm btn-success',
  426. 'label' => false,
  427. 'html_attributes' => array(
  428. 'data-toggle' => 'tooltip',
  429. 'title' => $this->get(TranslatorAdmin::class)->transAction('detail'),
  430. ),
  431. ]
  432. );
  433. $this->actionUpdate(
  434. $actions,
  435. Crud::PAGE_INDEX,
  436. ActionDefinition::DELETE,
  437. [
  438. 'icon' => 'trash',
  439. 'dropdown' => true,
  440. 'label' => $this->get(TranslatorAdmin::class)->transAction('delete'),
  441. 'class' => 'dropdown-item text-danger in-dropdown action-delete',
  442. ]
  443. );
  444. $this->actionUpdate(
  445. $actions,
  446. Crud::PAGE_INDEX,
  447. ActionDefinition::BATCH_DELETE,
  448. [
  449. 'class' => 'btn btn-sm btn-danger',
  450. 'icon' => 'trash',
  451. 'label' => $this->get(TranslatorAdmin::class)->transAction('delete'),
  452. ]
  453. );
  454. }
  455. public function buildEditActions(Actions $actions): void
  456. {
  457. $actions->add(Crud::PAGE_EDIT, ActionDefinition::INDEX);
  458. $actions->add(Crud::PAGE_EDIT, ActionDefinition::DELETE);
  459. $this->actionUpdate(
  460. $actions,
  461. Crud::PAGE_EDIT,
  462. ActionDefinition::SAVE_AND_RETURN,
  463. [
  464. 'add_class' => 'float-right ',
  465. 'icon' => 'check',
  466. 'label' => $this->get(TranslatorAdmin::class)->transAction('save_and_return'),
  467. ]
  468. );
  469. $this->actionUpdate(
  470. $actions,
  471. Crud::PAGE_EDIT,
  472. ActionDefinition::INDEX,
  473. [
  474. 'icon' => 'chevron-left',
  475. 'class' => 'btn btn-link',
  476. 'label' => $this->get(TranslatorAdmin::class)->transAction('back_index'),
  477. ]
  478. );
  479. $this->actionUpdate(
  480. $actions,
  481. Crud::PAGE_EDIT,
  482. ActionDefinition::SAVE_AND_CONTINUE,
  483. [
  484. 'class' => 'btn btn-info float-right action-save-continue',
  485. 'label' => $this->get(TranslatorAdmin::class)->transAction('save_and_continue'),
  486. ]
  487. );
  488. $this->actionUpdate(
  489. $actions,
  490. Crud::PAGE_EDIT,
  491. ActionDefinition::DELETE,
  492. [
  493. 'icon' => 'trash',
  494. 'class' => 'btn btn-outline-danger action-delete',
  495. 'label' => $this->get(TranslatorAdmin::class)->transAction('delete'),
  496. ]
  497. );
  498. }
  499. public function buildDetailActions(Actions $actions): void
  500. {
  501. }
  502. public function buildNewActions(Actions $actions): void
  503. {
  504. $actions->add(Crud::PAGE_NEW, ActionDefinition::INDEX);
  505. $this->actionUpdate(
  506. $actions,
  507. Crud::PAGE_EDIT,
  508. ActionDefinition::SAVE_AND_RETURN,
  509. [
  510. 'add_class' => 'float-right',
  511. 'icon' => 'check',
  512. 'label' => $this->get(TranslatorAdmin::class)->transAction('save_and_return'),
  513. ]
  514. );
  515. $this->actionUpdate(
  516. $actions,
  517. Crud::PAGE_EDIT,
  518. ActionDefinition::INDEX,
  519. [
  520. 'icon' => 'chevron-left',
  521. 'class' => 'btn btn-link',
  522. 'label' => $this->get(TranslatorAdmin::class)->transAction('back_index'),
  523. ]
  524. );
  525. $this->actionUpdate(
  526. $actions,
  527. Crud::PAGE_EDIT,
  528. ActionDefinition::SAVE_AND_ADD_ANOTHER,
  529. [
  530. 'class' => 'btn btn-info float-right',
  531. 'label' => $this->get(TranslatorAdmin::class)->transAction('save_and_add_another'),
  532. ]
  533. );
  534. }
  535. public function handleTranslatableEntityActions(Actions $actions): void
  536. {
  537. if ($this->isInstanceOf(TranslatableInterface::class)) {
  538. $actions->update(
  539. Crud::PAGE_INDEX,
  540. ActionDefinition::EDIT,
  541. function (Action $action) {
  542. $action->setTemplatePath('@LcSov/adminlte/crud/action/translatable.html.twig');
  543. return $action;
  544. }
  545. );
  546. }
  547. }
  548. public function handleSortableEntityActions(Actions $actions): void
  549. {
  550. if ($this->isInstanceOf(SortableInterface::class)) {
  551. $sortAction = Action::new(ActionDefinition::SORT, $this->get(TranslatorAdmin::class)->transAction(ActionDefinition::SORT), 'fa fa-sort')
  552. ->linkToCrudAction(ActionDefinition::SORT)
  553. ->setCssClass('btn btn-sm btn-success')
  554. ->createAsGlobalAction();
  555. $actions->add(Crud::PAGE_INDEX, $sortAction);
  556. }
  557. }
  558. public function handleTreeEntityActions(Actions $actions): void
  559. {
  560. if ($this->isInstanceOf(TreeInterface::class)) {
  561. $indexChildAction = Action::new(
  562. ActionDefinition::INDEX_CHILDREN,
  563. $this->get(TranslatorAdmin::class)->transAction(ActionDefinition::INDEX_CHILDREN),
  564. 'fa fa-list'
  565. )
  566. ->linkToCrudAction(ActionDefinition::INDEX)
  567. ->setLabel('')
  568. ->setHtmlAttributes(array('data-toggle' => 'tooltip', 'title' => 'Afficher les enfants'))
  569. ->setTemplatePath('@LcSov/adminlte/crud/action/index_children.html.twig')
  570. ->setCssClass('btn btn-sm btn-success');
  571. $backParentAction = Action::new(
  572. ActionDefinition::INDEX_PARENT,
  573. $this->get(TranslatorAdmin::class)->transAction(ActionDefinition::INDEX_PARENT),
  574. 'fa fa-chevron-left'
  575. )
  576. ->linkToCrudAction(ActionDefinition::INDEX)
  577. ->setCssClass('btn btn-sm btn-info')
  578. ->createAsGlobalAction();
  579. $actions->add(Crud::PAGE_INDEX, $backParentAction);
  580. $actions->add(Crud::PAGE_INDEX, $indexChildAction);
  581. }
  582. }
  583. public function actionUpdate($actions, $crudActionName, $actionName, array $button): void
  584. {
  585. if ($actions->getAsDto('actions')->getAction($crudActionName, $actionName)) {
  586. $actions->update(
  587. $crudActionName,
  588. $actionName,
  589. function (Action $action) use ($button) {
  590. if (isset($button['add_class'])) {
  591. $action->addCssClass($button['add_class']);
  592. }
  593. if (isset($button['class'])) {
  594. $action->setCssClass($button['class']);
  595. }
  596. if (isset($button['icon'])) {
  597. $action->setIcon('fa fa-' . $button['icon']);
  598. }
  599. if (isset($button['label'])) {
  600. $action->setLabel($button['label']);
  601. }
  602. if (isset($button['dropdown']) && $button['dropdown']) {
  603. $action->addCssClass('in-dropdown');
  604. }
  605. if (isset($button['html_attributes']) && $button['html_attributes']) {
  606. $action->setHtmlAttributes($button['html_attributes']);
  607. }
  608. return $action;
  609. }
  610. );
  611. }
  612. }
  613. public function autocompleteFilter(AdminContext $context): JsonResponse
  614. {
  615. $queryBuilder = $this->createIndexQueryBuilder(
  616. $context->getSearch(),
  617. $context->getEntity(),
  618. FieldCollection::new([]),
  619. FilterCollection::new()
  620. );
  621. $autocompleteContext = $context->getRequest()->get(AssociationField::PARAM_AUTOCOMPLETE_CONTEXT);
  622. /** @var CrudControllerInterface $controller */
  623. $controller = $this->get(ControllerFactory::class)->getCrudControllerInstance(
  624. $autocompleteContext[EA::CRUD_CONTROLLER_FQCN],
  625. ActionDefinition::INDEX,
  626. $context->getRequest()
  627. );
  628. /** @var FieldDto $field */
  629. $field = FieldCollection::new(
  630. $controller->configureFields($autocompleteContext['originatingPage'])
  631. )->getByProperty($autocompleteContext['propertyName']);
  632. $filterManager = $this->get(FilterManager::class);
  633. $filterManager->applyFilter($queryBuilder, $field, $context->getRequest()->query->get('q'));
  634. if ($filterManager->isRelationField($field->getProperty())) {
  635. $queryBuilder->select($autocompleteContext['propertyName']);
  636. } else {
  637. $queryBuilder->select('entity.' . $autocompleteContext['propertyName']);
  638. }
  639. $responses = array();
  640. foreach ($queryBuilder->getQuery()->getArrayResult() as $result) {
  641. $responses[] = array_values($result)[0];
  642. }
  643. return JsonResponse::fromJsonString(json_encode($responses));
  644. }
  645. public function createCustomForm($class, $action, $controller, $entity, $dataInOption = true, $options = array())
  646. {
  647. if ($dataInOption) {
  648. $data = $entity;
  649. }else{
  650. $data = null;
  651. }
  652. $options['action'] = $this->get(AdminUrlGenerator::class)
  653. ->setAction($action)
  654. ->setController($controller)
  655. ->setEntityId($entity->getId())
  656. ->generateUrl();
  657. return $this->createForm($class, $data, $options);
  658. }
  659. }