vendor/easycorp/easyadmin-bundle/src/Factory/ActionFactory.php line 44

Open in your IDE?
  1. <?php
  2. namespace EasyCorp\Bundle\EasyAdminBundle\Factory;
  3. use EasyCorp\Bundle\EasyAdminBundle\Collection\ActionCollection;
  4. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  5. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  6. use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA;
  7. use EasyCorp\Bundle\EasyAdminBundle\Dto\ActionConfigDto;
  8. use EasyCorp\Bundle\EasyAdminBundle\Dto\ActionDto;
  9. use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
  10. use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider;
  11. use EasyCorp\Bundle\EasyAdminBundle\Registry\DashboardControllerRegistry;
  12. use EasyCorp\Bundle\EasyAdminBundle\Router\CrudUrlGenerator;
  13. use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  16. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  17. use function Symfony\Component\String\u;
  18. use Symfony\Contracts\Translation\TranslatorInterface;
  19. /**
  20.  * @author Javier Eguiluz <javier.eguiluz@gmail.com>
  21.  */
  22. final class ActionFactory
  23. {
  24.     private $adminContextProvider;
  25.     private $dashboardRegistry;
  26.     private $authChecker;
  27.     private $translator;
  28.     private $urlGenerator;
  29.     private $crudUrlGenerator;
  30.     public function __construct(AdminContextProvider $adminContextProviderDashboardControllerRegistry $dashboardRegistryAuthorizationCheckerInterface $authCheckerTranslatorInterface $translatorUrlGeneratorInterface $urlGeneratorCrudUrlGenerator $crudUrlGenerator)
  31.     {
  32.         $this->adminContextProvider $adminContextProvider;
  33.         $this->dashboardRegistry $dashboardRegistry;
  34.         $this->authChecker $authChecker;
  35.         $this->translator $translator;
  36.         $this->urlGenerator $urlGenerator;
  37.         $this->crudUrlGenerator $crudUrlGenerator;
  38.     }
  39.     public function processEntityActions(EntityDto $entityDtoActionConfigDto $actionsDto): void
  40.     {
  41.         $currentPage $this->adminContextProvider->getContext()->getCrud()->getCurrentPage();
  42.         $entityActions = [];
  43.         foreach ($actionsDto->getActions()->all() as $actionDto) {
  44.             if (!$actionDto->isEntityAction()) {
  45.                 continue;
  46.             }
  47.             if (false === $this->authChecker->isGranted(Permission::EA_EXECUTE_ACTION$actionDto)) {
  48.                 continue;
  49.             }
  50.             if (false === $actionDto->shouldBeDisplayedFor($entityDto)) {
  51.                 continue;
  52.             }
  53.             $entityActions[] = $this->processAction($currentPage$actionDto$entityDto);
  54.         }
  55.         $entityDto->setActions(ActionCollection::new($entityActions));
  56.     }
  57.     public function processGlobalActions(ActionConfigDto $actionsDto): ActionCollection
  58.     {
  59.         $currentPage $this->adminContextProvider->getContext()->getCrud()->getCurrentPage();
  60.         $globalActions = [];
  61.         foreach ($actionsDto->getActions()->all() as $actionDto) {
  62.             if (!$actionDto->isGlobalAction()) {
  63.                 continue;
  64.             }
  65.             // TODO: remove this when we reenable "batch actions"
  66.             if ($actionDto->isBatchAction()) {
  67.                 throw new \RuntimeException(sprintf('Batch actions are not supported yet, but we\'ll add support for them very soon. Meanwhile, remove the "%s" batch action from the "%s" page.'$actionDto->getName(), $currentPage));
  68.             }
  69.             if (false === $this->authChecker->isGranted(Permission::EA_EXECUTE_ACTION$actionDto)) {
  70.                 continue;
  71.             }
  72.             if (Crud::PAGE_INDEX !== $currentPage && $actionDto->isBatchAction()) {
  73.                 throw new \RuntimeException(sprintf('Batch actions can be added only to the "index" page, but the "%s" batch action is defined in the "%s" page.'$actionDto->getName(), $currentPage));
  74.             }
  75.             $globalActions[] = $this->processAction($currentPage$actionDto);
  76.         }
  77.         return ActionCollection::new($globalActions);
  78.     }
  79.     private function processAction(string $pageNameActionDto $actionDto, ?EntityDto $entityDto null): ActionDto
  80.     {
  81.         $adminContext $this->adminContextProvider->getContext();
  82.         $dashboardControllerFqcn $adminContext->getDashboardControllerFqcn();
  83.         $adminContextId $this->dashboardRegistry->getContextIdByControllerFqcn($dashboardControllerFqcn);
  84.         $translationDomain $adminContext->getI18n()->getTranslationDomain();
  85.         $defaultTranslationParameters $adminContext->getI18n()->getTranslationParameters();
  86.         $currentPage $adminContext->getCrud()->getCurrentPage();
  87.         if (false === $actionDto->getLabel()) {
  88.             $actionDto->setHtmlAttributes(array_merge(['title' => $actionDto->getName()], $actionDto->getHtmlAttributes()));
  89.         } else {
  90.             $uLabel u($actionDto->getLabel());
  91.             // labels with this prefix are considered internal and must be translated
  92.             // with 'EasyAdminBundle' translation domain, regardlesss of the backend domain
  93.             if ($uLabel->startsWith('__ea__')) {
  94.                 $uLabel $uLabel->after('__ea__');
  95.                 $translationDomain 'EasyAdminBundle';
  96.             }
  97.             $translationParameters array_merge($defaultTranslationParameters$actionDto->getTranslationParameters());
  98.             $label $uLabel->toString();
  99.             $translatedActionLabel = empty($label) ? $label $this->translator->trans($label$translationParameters$translationDomain);
  100.             $actionDto->setLabel($translatedActionLabel);
  101.         }
  102.         $defaultTemplatePath $adminContext->getTemplatePath('crud/action');
  103.         $actionDto->setTemplatePath($actionDto->getTemplatePath() ?? $defaultTemplatePath);
  104.         $actionDto->setLinkUrl($this->generateActionUrl($adminContextId$currentPage$adminContext->getRequest(), $actionDto$entityDto));
  105.         if (!$actionDto->isGlobalAction() && \in_array($pageName, [Crud::PAGE_EDITCrud::PAGE_NEW], true)) {
  106.             $actionDto->setHtmlAttribute('form'sprintf('%s-%s-form'$pageName$entityDto->getName()));
  107.         }
  108.         return $actionDto;
  109.     }
  110.     private function generateActionUrl(string $adminContextIdstring $currentActionRequest $requestActionDto $actionDto, ?EntityDto $entityDto null): string
  111.     {
  112.         if (null !== $url $actionDto->getUrl()) {
  113.             if (\is_callable($url)) {
  114.                 return $url($entityDto->getInstance());
  115.             }
  116.             return $url;
  117.         }
  118.         if (null !== $routeName $actionDto->getRouteName()) {
  119.             $routeParameters $actionDto->getRouteParameters();
  120.             if (\is_callable($routeParameters) && null !== $entityInstance $entityDto->getInstance()) {
  121.                 $routeParameters $routeParameters($entityInstance);
  122.             }
  123.             $routeParameters array_merge([EA::CONTEXT_NAME => $adminContextId], $routeParameters);
  124.             return $this->urlGenerator->generate($routeName$routeParameters);
  125.         }
  126.         $requestParameters = [
  127.             EA::CRUD_ID => $request->query->get(EA::CRUD_ID),
  128.             EA::CRUD_ACTION => $actionDto->getCrudActionName(),
  129.             EA::REFERRER => $this->generateReferrerUrl($request$actionDto$currentAction),
  130.         ];
  131.         if (\in_array($actionDto->getName(), [Action::INDEXAction::NEW], true)) {
  132.             $requestParameters[EA::ENTITY_ID] = null;
  133.         } elseif (null !== $entityDto) {
  134.             $requestParameters[EA::ENTITY_ID] = $entityDto->getPrimaryKeyValueAsString();
  135.         }
  136.         return $this->crudUrlGenerator->build($requestParameters)->generateUrl();
  137.     }
  138.     private function generateReferrerUrl(Request $requestActionDto $actionDtostring $currentAction): ?string
  139.     {
  140.         $nextAction $actionDto->getName();
  141.         if (Action::DETAIL === $currentAction) {
  142.             if (Action::EDIT === $nextAction) {
  143.                 return $this->crudUrlGenerator->build()->removeReferrer()->generateUrl();
  144.             }
  145.         }
  146.         if (Action::INDEX === $currentAction) {
  147.             return $this->crudUrlGenerator->build()->removeReferrer()->generateUrl();
  148.         }
  149.         if (Action::NEW === $currentAction) {
  150.             return null;
  151.         }
  152.         $referrer $request->get(EA::REFERRER);
  153.         $referrerParts parse_url($referrer);
  154.         parse_str($referrerParts[EA::QUERY] ?? ''$referrerQueryStringVariables);
  155.         $referrerCrudAction $referrerQueryStringVariables[EA::CRUD_ACTION] ?? null;
  156.         if (Action::EDIT === $currentAction) {
  157.             if (\in_array($referrerCrudAction, [Action::INDEXAction::DETAIL], true)) {
  158.                 return $referrer;
  159.             }
  160.         }
  161.         return $this->crudUrlGenerator->build()->removeReferrer()->generateUrl();
  162.     }
  163. }