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

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\Router\AdminUrlGenerator;
  12. use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  15. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  16. use function Symfony\Component\String\u;
  17. use Symfony\Contracts\Translation\TranslatorInterface;
  18. /**
  19.  * @author Javier Eguiluz <javier.eguiluz@gmail.com>
  20.  */
  21. final class ActionFactory
  22. {
  23.     private $adminContextProvider;
  24.     private $authChecker;
  25.     private $translator;
  26.     private $adminUrlGenerator;
  27.     private $csrfTokenManager;
  28.     public function __construct(AdminContextProvider $adminContextProviderAuthorizationCheckerInterface $authCheckerTranslatorInterface $translatorAdminUrlGenerator $adminUrlGeneratorCsrfTokenManagerInterface $csrfTokenManager)
  29.     {
  30.         $this->adminContextProvider $adminContextProvider;
  31.         $this->authChecker $authChecker;
  32.         $this->translator $translator;
  33.         $this->adminUrlGenerator $adminUrlGenerator;
  34.         $this->csrfTokenManager $csrfTokenManager;
  35.     }
  36.     public function processEntityActions(EntityDto $entityDtoActionConfigDto $actionsDto): void
  37.     {
  38.         $currentPage $this->adminContextProvider->getContext()->getCrud()->getCurrentPage();
  39.         $entityActions = [];
  40.         foreach ($actionsDto->getActions()->all() as $actionDto) {
  41.             if (!$actionDto->isEntityAction()) {
  42.                 continue;
  43.             }
  44.             if (false === $this->authChecker->isGranted(Permission::EA_EXECUTE_ACTION, ['action' => $actionDto'entity' => $entityDto])) {
  45.                 continue;
  46.             }
  47.             if (false === $actionDto->shouldBeDisplayedFor($entityDto)) {
  48.                 continue;
  49.             }
  50.             if ('' === $actionDto->getCssClass()) {
  51.                 $defaultCssClass 'action-'.$actionDto->getName();
  52.                 if (Crud::PAGE_INDEX !== $currentPage) {
  53.                     $defaultCssClass .= ' btn';
  54.                 }
  55.                 $actionDto->setCssClass($defaultCssClass);
  56.             }
  57.             $entityActions[] = $this->processAction($currentPage$actionDto$entityDto);
  58.         }
  59.         $entityDto->setActions(ActionCollection::new($entityActions));
  60.     }
  61.     public function processGlobalActions(ActionConfigDto $actionsDto null): ActionCollection
  62.     {
  63.         if (null === $actionsDto) {
  64.             $actionsDto $this->adminContextProvider->getContext()->getCrud()->getActionsConfig();
  65.         }
  66.         $currentPage $this->adminContextProvider->getContext()->getCrud()->getCurrentPage();
  67.         $globalActions = [];
  68.         foreach ($actionsDto->getActions()->all() as $actionDto) {
  69.             if (!$actionDto->isGlobalAction() && !$actionDto->isBatchAction()) {
  70.                 continue;
  71.             }
  72.             if (false === $this->authChecker->isGranted(Permission::EA_EXECUTE_ACTION, ['action' => $actionDto'entity' => null])) {
  73.                 continue;
  74.             }
  75.             if (Crud::PAGE_INDEX !== $currentPage && $actionDto->isBatchAction()) {
  76.                 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));
  77.             }
  78.             if ('' === $actionDto->getCssClass()) {
  79.                 $actionDto->setCssClass('btn action-'.$actionDto->getName());
  80.             }
  81.             $globalActions[] = $this->processAction($currentPage$actionDto);
  82.         }
  83.         return ActionCollection::new($globalActions);
  84.     }
  85.     private function processAction(string $pageNameActionDto $actionDto, ?EntityDto $entityDto null): ActionDto
  86.     {
  87.         $adminContext $this->adminContextProvider->getContext();
  88.         $translationDomain $adminContext->getI18n()->getTranslationDomain();
  89.         $defaultTranslationParameters $adminContext->getI18n()->getTranslationParameters();
  90.         $currentPage $adminContext->getCrud()->getCurrentPage();
  91.         $actionDto->setHtmlAttribute('data-action-name'$actionDto->getName());
  92.         if (false === $actionDto->getLabel()) {
  93.             $actionDto->setHtmlAttribute('title'$actionDto->getName());
  94.         } else {
  95.             $uLabel u($actionDto->getLabel());
  96.             // labels with this prefix are considered internal and must be translated
  97.             // with 'EasyAdminBundle' translation domain, regardless of the backend domain
  98.             if ($uLabel->startsWith('__ea__')) {
  99.                 $uLabel $uLabel->after('__ea__');
  100.                 $translationDomain 'EasyAdminBundle';
  101.             }
  102.             $translationParameters array_merge($defaultTranslationParameters$actionDto->getTranslationParameters());
  103.             $label $uLabel->toString();
  104.             $translatedActionLabel = empty($label) ? $label $this->translator->trans($label$translationParameters$translationDomain);
  105.             $actionDto->setLabel($translatedActionLabel);
  106.         }
  107.         $defaultTemplatePath $adminContext->getTemplatePath('crud/action');
  108.         $actionDto->setTemplatePath($actionDto->getTemplatePath() ?? $defaultTemplatePath);
  109.         $actionDto->setLinkUrl($this->generateActionUrl($currentPage$adminContext->getRequest(), $actionDto$entityDto));
  110.         if (!$actionDto->isGlobalAction() && \in_array($pageName, [Crud::PAGE_EDITCrud::PAGE_NEW], true)) {
  111.             $actionDto->setHtmlAttribute('form'sprintf('%s-%s-form'$pageName$entityDto->getName()));
  112.         }
  113.         if (Action::DELETE === $actionDto->getName()) {
  114.             $actionDto->addHtmlAttributes([
  115.                 'formaction' => $this->adminUrlGenerator->setAction(Action::DELETE)->setEntityId($entityDto->getPrimaryKeyValue())->removeReferrer()->generateUrl(),
  116.                 'data-bs-toggle' => 'modal',
  117.                 'data-bs-target' => '#modal-delete',
  118.             ]);
  119.         }
  120.         if ($actionDto->isBatchAction()) {
  121.             $actionDto->addHtmlAttributes([
  122.                 'data-bs-toggle' => 'modal',
  123.                 'data-bs-target' => '#modal-batch-action',
  124.                 'data-action-csrf-token' => $this->csrfTokenManager->getToken('ea-batch-action-'.$actionDto->getName()),
  125.                 'data-action-batch' => 'true',
  126.                 'data-entity-fqcn' => $adminContext->getCrud()->getEntityFqcn(),
  127.                 'data-action-url' => $actionDto->getLinkUrl(),
  128.             ]);
  129.         }
  130.         return $actionDto;
  131.     }
  132.     private function generateActionUrl(string $currentActionRequest $requestActionDto $actionDto, ?EntityDto $entityDto null): string
  133.     {
  134.         if (null !== $url $actionDto->getUrl()) {
  135.             if (\is_callable($url)) {
  136.                 return null !== $entityDto $url($entityDto->getInstance()) : $url();
  137.             }
  138.             return $url;
  139.         }
  140.         if (null !== $routeName $actionDto->getRouteName()) {
  141.             $routeParameters $actionDto->getRouteParameters();
  142.             if (\is_callable($routeParameters) && null !== $entityInstance $entityDto->getInstance()) {
  143.                 $routeParameters $routeParameters($entityInstance);
  144.             }
  145.             return $this->adminUrlGenerator->unsetAllExcept(EA::MENU_INDEXEA::SUBMENU_INDEX)->includeReferrer()->setRoute($routeName$routeParameters)->generateUrl();
  146.         }
  147.         $requestParameters = [
  148.             EA::CRUD_CONTROLLER_FQCN => $request->query->get(EA::CRUD_CONTROLLER_FQCN),
  149.             EA::CRUD_ACTION => $actionDto->getCrudActionName(),
  150.             EA::REFERRER => $this->generateReferrerUrl($request$actionDto$currentAction),
  151.         ];
  152.         if (\in_array($actionDto->getName(), [Action::INDEXAction::NEW, Action::SAVE_AND_ADD_ANOTHERAction::SAVE_AND_RETURN], true)) {
  153.             $requestParameters[EA::ENTITY_ID] = null;
  154.         } elseif (null !== $entityDto) {
  155.             $requestParameters[EA::ENTITY_ID] = $entityDto->getPrimaryKeyValueAsString();
  156.         }
  157.         return $this->adminUrlGenerator->unsetAllExcept(EA::MENU_INDEXEA::SUBMENU_INDEXEA::FILTERSEA::PAGE)->setAll($requestParameters)->generateUrl();
  158.     }
  159.     private function generateReferrerUrl(Request $requestActionDto $actionDtostring $currentAction): ?string
  160.     {
  161.         $nextAction $actionDto->getName();
  162.         if (Action::DETAIL === $currentAction) {
  163.             if (Action::EDIT === $nextAction) {
  164.                 return $this->adminUrlGenerator->removeReferrer()->generateUrl();
  165.             }
  166.         }
  167.         if (Action::INDEX === $currentAction) {
  168.             return $this->adminUrlGenerator->removeReferrer()->generateUrl();
  169.         }
  170.         if (Action::NEW === $currentAction) {
  171.             return null;
  172.         }
  173.         $referrer $request->query->get(EA::REFERRER);
  174.         $referrerParts parse_url((string) $referrer);
  175.         parse_str($referrerParts[EA::QUERY] ?? ''$referrerQueryStringVariables);
  176.         $referrerCrudAction $referrerQueryStringVariables[EA::CRUD_ACTION] ?? null;
  177.         if (Action::EDIT === $currentAction) {
  178.             if (\in_array($referrerCrudAction, [Action::INDEXAction::DETAIL], true)) {
  179.                 return $referrer;
  180.             }
  181.         }
  182.         return $this->adminUrlGenerator->removeReferrer()->generateUrl();
  183.     }
  184. }