Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

771 lines
29KB

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