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.

AbstractAdminController.php 30KB

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