Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

AbstractAdminController.php 27KB

3 lat temu
3 lat temu
3 lat temu
3 lat temu
3 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  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 Lc\SovBundle\Doctrine\Extension\DevAliasInterface;
  37. use Lc\SovBundle\Doctrine\Extension\SeoInterface;
  38. use Lc\SovBundle\Doctrine\Extension\SortableInterface;
  39. use Lc\SovBundle\Doctrine\Extension\TranslatableInterface;
  40. use Lc\SovBundle\Doctrine\Extension\TreeInterface;
  41. use Lc\SovBundle\Field\CollectionField;
  42. use Lc\SovBundle\Field\Filter\FilterManager;
  43. use Lc\SovBundle\Form\Common\FiltersFormType;
  44. use Lc\SovBundle\Form\Common\PositionType;
  45. use Lc\SovBundle\Translation\TranslatorAdmin;
  46. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  47. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  48. use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
  49. use Symfony\Component\Form\Extension\Core\Type\DateType;
  50. use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  51. use Symfony\Component\Form\Extension\Core\Type\TextType;
  52. use Symfony\Component\HttpFoundation\JsonResponse;
  53. use Symfony\Component\HttpFoundation\RequestStack;
  54. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  55. abstract class AbstractAdminController extends EaAbstractCrudController
  56. {
  57. protected $filtersForm;
  58. public static function getSubscribedServices()
  59. {
  60. return array_merge(
  61. parent::getSubscribedServices(),
  62. [
  63. 'session' => SessionInterface::class,
  64. 'request' => RequestStack::class,
  65. 'em' => EntityManagerInterface::class,
  66. 'translator_admin' => TranslatorAdmin::class,
  67. 'filter_manager' => FilterManager::class,
  68. ]
  69. );
  70. }
  71. public function configureResponseParameters(KeyValueStore $responseParameters): KeyValueStore
  72. {
  73. $this->overrideGlobalActions($responseParameters->get('global_actions'));
  74. $this->overrideEntitiesActions($responseParameters->get('entities'));
  75. if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) {
  76. $responseParameters->set('fields', $this->configureFields('index'));
  77. if ($this->filtersForm === null) {
  78. die('nncncd');
  79. //TODO delete under code
  80. $options['fields'] = $responseParameters->get('fields');
  81. $options['entity_class'] = $this->getEntityFqcn();
  82. $options['entity_name'] = $responseParameters->get('entity')->getName();
  83. $this->filtersForm = $this->createForm(FiltersFormType::class, null, $options);
  84. }
  85. $responseParameters->set('filters_form', $this->filtersForm);
  86. }
  87. return $responseParameters;
  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. if ($this->isInstanceOf(SortableInterface::class)) {
  132. $crud->setDefaultSort(['position' => 'ASC']);
  133. }
  134. return $crud;
  135. }
  136. public function setMaxResults(Crud $crud): void
  137. {
  138. $entityClass = $this->getEntityFqcn();
  139. $paramListMaxResults = 'listMaxResults';
  140. $paramSessionListMaxResults = $entityClass.'-'.$paramListMaxResults;
  141. $requestListMaxResults = $this->get('request')->getCurrentRequest()->get($paramListMaxResults);
  142. if ($requestListMaxResults) {
  143. $this->get('session')->set($paramSessionListMaxResults, $requestListMaxResults);
  144. }
  145. $maxResults = $this->get('session')->get($paramSessionListMaxResults) ? $this->get('session')->get(
  146. $paramSessionListMaxResults
  147. ) : 30;
  148. $crud->setPaginatorPageSize($maxResults);
  149. }
  150. public function configureFields(string $pageName): iterable
  151. {
  152. $seoPanel = $confPanel = array();
  153. if ($this->isInstanceOf(SeoInterface::class)) {
  154. $seoPanel = [
  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. }
  168. if ($this->isInstanceOf(DevAliasInterface::class)) {
  169. $confPanel = [
  170. FormField::addPanel('configuration')->setTemplateName('crud/field/generic'),
  171. TextField::new('devAlias')->hideOnIndex(),
  172. ];
  173. }
  174. return array_merge($seoPanel, $confPanel);
  175. }
  176. public function sort(AdminContext $context)
  177. {
  178. $event = new BeforeCrudActionEvent($context);
  179. $this->get('event_dispatcher')->dispatch($event);
  180. if ($event->isPropagationStopped()) {
  181. return $event->getResponse();
  182. }
  183. //if (!$this->isGranted(Permission::EA_EXECUTE_ACTION) || !$this->isInstanceOf(SortableInterface::class)) {
  184. if (!$this->isInstanceOf(SortableInterface::class)) {
  185. throw new ForbiddenActionException($context);
  186. }
  187. $fields = FieldCollection::new($this->configureFields(Crud::PAGE_INDEX));
  188. $filters = $this->get(FilterFactory::class)->create(
  189. $context->getCrud()->getFiltersConfig(),
  190. $fields,
  191. $context->getEntity()
  192. );
  193. $queryBuilder = $this->createIndexQueryBuilder($context->getSearch(), $context->getEntity(), $fields, $filters);
  194. $paginator = $this->get(PaginatorFactory::class)->create($queryBuilder);
  195. $entities = $this->get(EntityFactory::class)->createCollection($context->getEntity(), $paginator->getResults());
  196. $this->get(EntityFactory::class)->processFieldsForAll($entities, $fields);
  197. $sortableForm = $this->createFormBuilder(array('entities', $paginator->getResults()))
  198. ->add(
  199. 'entities',
  200. CollectionType::class,
  201. array(
  202. 'required' => true,
  203. 'allow_add' => true,
  204. 'entry_type' => PositionType::class,
  205. )
  206. )
  207. ->getForm();
  208. $entityManager = $this->getDoctrine()->getManagerForClass($this->getEntityFqcn());
  209. $repository = $entityManager->getRepository($this->getEntityFqcn());
  210. $sortableForm->handleRequest($context->getRequest());
  211. if ($sortableForm->isSubmitted() && $sortableForm->isValid()) {
  212. foreach ($sortableForm->get('entities')->getData() as $elm) {
  213. $entityInstance = $repository->find($elm['id']);
  214. $entityDto = $context->getEntity()->newWithInstance($entityInstance);
  215. if (!$entityDto->isAccessible()) {
  216. throw new InsufficientEntityPermissionException($context);
  217. }
  218. $event = new BeforeEntityDeletedEvent($entityInstance);
  219. $this->get('event_dispatcher')->dispatch($event);
  220. $entityInstance = $event->getEntityInstance();
  221. $entityInstance->setPosition($elm['position']);
  222. $this->updateEntity($entityManager, $entityInstance);
  223. $this->get('event_dispatcher')->dispatch(new AfterEntityUpdatedEvent($entityInstance));
  224. }
  225. $url = $this->get(AdminUrlGenerator::class)
  226. ->setAction(Action::INDEX)
  227. ->generateUrl();
  228. $this->addFlash('success', $this->translatorAdmin->transFlashMessage('sort'), array());
  229. return $this->redirect($url);
  230. }
  231. $responseParameters = $this->configureResponseParameters(
  232. KeyValueStore::new(
  233. [
  234. 'pageName' => Crud::PAGE_INDEX,
  235. 'templatePath' => '@LcSov/adminlte/crud/sort.html.twig',
  236. 'entities' => $entities,
  237. 'paginator' => $paginator,
  238. 'global_actions' => array(),
  239. 'batch_actions' => array(),
  240. 'filters' => $filters,
  241. 'sortable_form' => $sortableForm,
  242. ]
  243. )
  244. );
  245. $responseParameters->set('fields', $this->configureFields('index'));
  246. $event = new AfterCrudActionEvent($context, $responseParameters);
  247. $this->get('event_dispatcher')->dispatch($event);
  248. if ($event->isPropagationStopped()) {
  249. return $event->getResponse();
  250. }
  251. return $responseParameters;
  252. }
  253. public function createIndexQueryBuilder(
  254. SearchDto $searchDto,
  255. EntityDto $entityDto,
  256. FieldCollection $fields,
  257. FilterCollection $filters
  258. ): QueryBuilder {
  259. $queryBuilder = parent::createIndexQueryBuilder(
  260. $searchDto,
  261. $entityDto,
  262. $fields,
  263. $filters
  264. );
  265. //TOdo utiliser les repositoryQuery ?
  266. if ($this->isInstanceOf(TreeInterface::class)) {
  267. $entityId = $searchDto->getRequest()->get('entityId');
  268. if ($entityId !== null) {
  269. $queryBuilder->andWhere('entity.parent = :entityId');
  270. $queryBuilder->setParameter('entityId', $searchDto->getRequest()->get('entityId'));
  271. } else {
  272. $queryBuilder->andWhere('entity.parent IS NULL');
  273. }
  274. }
  275. $this->filtersForm = $this->createForm(
  276. FiltersFormType::class,
  277. null,
  278. array(
  279. 'fields' => $fields,
  280. 'entity_dto' => $entityDto,
  281. 'entity_class' => $this->getEntityFqcn(),
  282. 'entity_name' => $entityDto->getName(),
  283. )
  284. );
  285. $filterManager = $this->get('filter_manager');
  286. $this->filtersForm->handleRequest($searchDto->getRequest());
  287. /*if (($this->filtersForm->isSubmitted() && $this->filtersForm->isValid())) {
  288. }*/
  289. $filterManager->handleFiltersForm($queryBuilder, $this->filtersForm, $fields, $entityDto);
  290. return $queryBuilder;
  291. }
  292. public function createSortQueryBuilder(
  293. SearchDto $searchDto,
  294. EntityDto $entityDto,
  295. FieldCollection $fields,
  296. FilterCollection $filters
  297. ): QueryBuilder {
  298. $queryBuilder = $this->createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
  299. return $queryBuilder;
  300. }
  301. public function edit(AdminContext $context)
  302. {
  303. $response = parent::edit($context);;
  304. // on vide le flash bag si édition en ajax (notification déjà affichée en Javascript)
  305. if ($context->getRequest()->isXmlHttpRequest()) {
  306. $this->get('session')->getFlashBag()->clear();
  307. }
  308. return $response;
  309. }
  310. public function isInstanceOf(string $interfaceName): bool
  311. {
  312. return in_array($interfaceName, class_implements($this->getEntityFqcn()));
  313. }
  314. public function getControllerFqcnByInterface(string $interface): string
  315. {
  316. $context = $this->get(AdminContextProvider::class)->getContext();
  317. return $context->getCrudControllers()->findCrudFqcnByEntityFqcn(
  318. $this->get('em')->getEntityName($interface)
  319. );
  320. }
  321. public function updateEntity(EntityManagerInterface $entityManager, $entityInstance): void
  322. {
  323. $entityManager->update($entityInstance);
  324. $entityManager->flush();
  325. }
  326. public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
  327. {
  328. $entityManager->create($entityInstance);
  329. $entityManager->flush();
  330. }
  331. public function configureActions(Actions $actions): Actions
  332. {
  333. $this->buildIndexActions($actions);
  334. $this->buildEditActions($actions);
  335. $this->buildDetailActions($actions);
  336. $this->buildNewActions($actions);
  337. $this->handleTranslatableEntityActions($actions);
  338. $this->handleSortableEntityActions($actions);
  339. $this->handleTreeEntityActions($actions);
  340. /*$actions->reorder(Crud::PAGE_EDIT, [Action::INDEX, Action::SAVE_AND_RETURN, Action::SAVE_AND_CONTINUE, Action::DELETE]);
  341. $actions->reorder(Crud::PAGE_NEW, [Action::INDEX, Action::SAVE_AND_RETURN, Action::SAVE_AND_ADD_ANOTHER]);*/
  342. return $actions;
  343. }
  344. public function buildIndexActions(Actions $actions): void
  345. {
  346. $this->actionUpdate(
  347. $actions,
  348. Crud::PAGE_INDEX,
  349. Action::NEW,
  350. [
  351. 'icon' => 'plus',
  352. 'label' => $this->get('translator_admin')->transAction('create'),
  353. 'add_class' => 'btn-sm',
  354. ]
  355. );
  356. $this->actionUpdate(
  357. $actions,
  358. Crud::PAGE_INDEX,
  359. Action::EDIT,
  360. [
  361. 'class' => 'btn btn-sm btn-primary',
  362. 'icon' => 'edit',
  363. 'label' => false,
  364. 'html_attributes' => array(
  365. 'data-toggle' => 'tooltip',
  366. 'title' => $this->get('translator_admin')->transAction('edit'),
  367. ),
  368. ]
  369. );
  370. $this->actionUpdate(
  371. $actions,
  372. Crud::PAGE_INDEX,
  373. Action::DETAIL,
  374. [
  375. 'icon' => 'eye',
  376. 'add_class' => 'btn btn-sm btn-success',
  377. 'label' => false,
  378. 'html_attributes' => array(
  379. 'data-toggle' => 'tooltip',
  380. 'title' => $this->get('translator_admin')->transAction('detail'),
  381. ),
  382. ]
  383. );
  384. $this->actionUpdate(
  385. $actions,
  386. Crud::PAGE_INDEX,
  387. Action::DELETE,
  388. [
  389. 'icon' => 'trash',
  390. 'dropdown' => true,
  391. 'label' => $this->get('translator_admin')->transAction('delete'),
  392. ]
  393. );
  394. $this->actionUpdate(
  395. $actions,
  396. Crud::PAGE_INDEX,
  397. Action::BATCH_DELETE,
  398. [
  399. 'class' => 'btn btn-sm btn-danger',
  400. 'icon' => 'trash',
  401. 'label' => $this->get('translator_admin')->transAction('delete'),
  402. ]
  403. );
  404. }
  405. public function buildEditActions(Actions $actions): void
  406. {
  407. $actions->add(Crud::PAGE_EDIT, Action::INDEX);
  408. $actions->add(Crud::PAGE_EDIT, Action::DELETE);
  409. $this->actionUpdate(
  410. $actions,
  411. Crud::PAGE_EDIT,
  412. Action::SAVE_AND_RETURN,
  413. [
  414. 'add_class' => 'float-right',
  415. 'icon' => 'check',
  416. 'label' => $this->get('translator_admin')->transAction('save_and_return'),
  417. ]
  418. );
  419. $this->actionUpdate(
  420. $actions,
  421. Crud::PAGE_EDIT,
  422. Action::INDEX,
  423. [
  424. 'icon' => 'chevron-left',
  425. 'class' => 'btn btn-link',
  426. 'label' => $this->get('translator_admin')->transAction('back_index'),
  427. ]
  428. );
  429. $this->actionUpdate(
  430. $actions,
  431. Crud::PAGE_EDIT,
  432. Action::SAVE_AND_CONTINUE,
  433. [
  434. 'class' => 'btn btn-info float-right',
  435. 'label' => $this->get('translator_admin')->transAction('save_and_continue'),
  436. ]
  437. );
  438. $this->actionUpdate(
  439. $actions,
  440. Crud::PAGE_EDIT,
  441. Action::DELETE,
  442. [
  443. 'icon' => 'trash',
  444. 'class' => 'btn btn-outline-danger action-delete',
  445. 'label' => $this->get('translator_admin')->transAction('delete'),
  446. ]
  447. );
  448. }
  449. public function buildDetailActions(Actions $actions): void
  450. {
  451. }
  452. public function buildNewActions(Actions $actions): void
  453. {
  454. $actions->add(Crud::PAGE_NEW, Action::INDEX);
  455. $this->actionUpdate(
  456. $actions,
  457. Crud::PAGE_EDIT,
  458. Action::SAVE_AND_RETURN,
  459. [
  460. 'add_class' => 'float-right',
  461. 'icon' => 'check',
  462. 'label' => $this->get('translator_admin')->transAction('save_and_return'),
  463. ]
  464. );
  465. $this->actionUpdate(
  466. $actions,
  467. Crud::PAGE_EDIT,
  468. Action::INDEX,
  469. [
  470. 'icon' => 'chevron-left',
  471. 'class' => 'btn btn-link',
  472. 'label' => $this->get('translator_admin')->transAction('back_index'),
  473. ]
  474. );
  475. $this->actionUpdate(
  476. $actions,
  477. Crud::PAGE_EDIT,
  478. Action::SAVE_AND_ADD_ANOTHER,
  479. [
  480. 'class' => 'btn btn-info float-right',
  481. 'label' => $this->get('translator_admin')->transAction('save_and_add_another'),
  482. ]
  483. );
  484. }
  485. public function handleTranslatableEntityActions(Actions $actions): void
  486. {
  487. if ($this->isInstanceOf(TranslatableInterface::class)) {
  488. $actions->update(
  489. Crud::PAGE_INDEX,
  490. Action::EDIT,
  491. function (Action $action) {
  492. $action->setTemplatePath('@LcSov/adminlte/crud/action/translatable.html.twig');
  493. return $action;
  494. }
  495. );
  496. }
  497. }
  498. public function handleSortableEntityActions(Actions $actions): void
  499. {
  500. if ($this->isInstanceOf(SortableInterface::class)) {
  501. $sortAction = Action::new('sort', $this->get('translator_admin')->transAction('sort'), 'fa fa-sort')
  502. ->linkToCrudAction('sort')
  503. ->setCssClass('btn btn-sm btn-success')
  504. ->createAsGlobalAction();
  505. $actions->add(Crud::PAGE_INDEX, $sortAction);
  506. }
  507. }
  508. public function handleTreeEntityActions(Actions $actions): void
  509. {
  510. if ($this->isInstanceOf(TreeInterface::class)) {
  511. $indexChildAction = Action::new(
  512. 'index_children',
  513. $this->get('translator_admin')->transAction('index_children'),
  514. 'fa fa-list'
  515. )
  516. ->linkToCrudAction(Action::INDEX)
  517. ->setLabel('')
  518. ->setHtmlAttributes(array('data-toggle' => 'tooltip', 'title' => 'Afficher les enfants'))
  519. ->setTemplatePath('@LcSov/adminlte/crud/action/index_children.html.twig')
  520. ->setCssClass('btn btn-sm btn-success');
  521. $backParentAction = Action::new(
  522. 'index_parent',
  523. $this->get('translator_admin')->transAction('index_parent'),
  524. 'fa fa-chevron-left'
  525. )
  526. ->linkToCrudAction(Action::INDEX)
  527. ->setCssClass('btn btn-sm btn-info')
  528. ->createAsGlobalAction();
  529. $actions->add(Crud::PAGE_INDEX, $backParentAction);
  530. $actions->add(Crud::PAGE_INDEX, $indexChildAction);
  531. }
  532. }
  533. public function actionUpdate($actions, $crudActionName, $actionName, array $button): void
  534. {
  535. if ($actions->getAsDto('actions')->getAction($crudActionName, $actionName)) {
  536. $actions->update(
  537. $crudActionName,
  538. $actionName,
  539. function (Action $action) use ($button) {
  540. if (isset($button['add_class'])) {
  541. $action->addCssClass($button['add_class']);
  542. }
  543. if (isset($button['class'])) {
  544. $action->setCssClass($button['class']);
  545. }
  546. if (isset($button['icon'])) {
  547. $action->setIcon('fa fa-'.$button['icon']);
  548. }
  549. if (isset($button['label'])) {
  550. $action->setLabel($button['label']);
  551. }
  552. if (isset($button['dropdown']) && $button['dropdown']) {
  553. $action->addCssClass('in-dropdown');
  554. }
  555. if (isset($button['html_attributes']) && $button['html_attributes']) {
  556. $action->setHtmlAttributes($button['html_attributes']);
  557. }
  558. return $action;
  559. }
  560. );
  561. }
  562. }
  563. public function autocompleteFilter(AdminContext $context): JsonResponse
  564. {
  565. $queryBuilder = $this->createIndexQueryBuilder(
  566. $context->getSearch(),
  567. $context->getEntity(),
  568. FieldCollection::new([]),
  569. FilterCollection::new()
  570. );
  571. $autocompleteContext = $context->getRequest()->get(AssociationField::PARAM_AUTOCOMPLETE_CONTEXT);
  572. /** @var CrudControllerInterface $controller */
  573. $controller = $this->get(ControllerFactory::class)->getCrudControllerInstance(
  574. $autocompleteContext[EA::CRUD_CONTROLLER_FQCN],
  575. Action::INDEX,
  576. $context->getRequest()
  577. );
  578. /** @var FieldDto $field */
  579. $field = FieldCollection::new(
  580. $controller->configureFields($autocompleteContext['originatingPage'])
  581. )->getByProperty($autocompleteContext['propertyName']);
  582. $filterManager = $this->get('filter_manager');
  583. $filterManager->applyFilter($queryBuilder, $field, $context->getRequest()->query->get('q'));
  584. if ($filterManager->isRelationField($field->getProperty())) {
  585. $queryBuilder->select($autocompleteContext['propertyName']);
  586. } else {
  587. $queryBuilder->select('entity.'.$autocompleteContext['propertyName']);
  588. }
  589. $responses = array();
  590. foreach ($queryBuilder->getQuery()->getArrayResult() as $result) {
  591. $responses[] = array_values($result)[0];
  592. }
  593. return JsonResponse::fromJsonString(json_encode($responses));
  594. }
  595. }