vendor/easycorp/easyadmin-bundle/src/Factory/AdminContextFactory.php line 215

Open in your IDE?
  1. <?php
  2. namespace EasyCorp\Bundle\EasyAdminBundle\Factory;
  3. use EasyCorp\Bundle\EasyAdminBundle\Cache\CacheWarmer;
  4. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  5. use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA;
  6. use EasyCorp\Bundle\EasyAdminBundle\Config\Option\TextDirection;
  7. use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
  8. use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface;
  9. use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface;
  10. use EasyCorp\Bundle\EasyAdminBundle\Dto\ActionConfigDto;
  11. use EasyCorp\Bundle\EasyAdminBundle\Dto\AssetsDto;
  12. use EasyCorp\Bundle\EasyAdminBundle\Dto\CrudDto;
  13. use EasyCorp\Bundle\EasyAdminBundle\Dto\DashboardDto;
  14. use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
  15. use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterConfigDto;
  16. use EasyCorp\Bundle\EasyAdminBundle\Dto\I18nDto;
  17. use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
  18. use EasyCorp\Bundle\EasyAdminBundle\Registry\CrudControllerRegistry;
  19. use EasyCorp\Bundle\EasyAdminBundle\Registry\TemplateRegistry;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  22. use Symfony\Component\Security\Core\User\UserInterface;
  23. use function Symfony\Component\String\u;
  24. use Symfony\Contracts\Translation\TranslatorInterface;
  25. /**
  26. * @author Javier Eguiluz <javier.eguiluz@gmail.com>
  27. */
  28. final class AdminContextFactory
  29. {
  30. private $cacheDir;
  31. private $translator;
  32. private $tokenStorage;
  33. private $menuFactory;
  34. private $crudControllers;
  35. private $entityFactory;
  36. public function __construct(string $cacheDir, TranslatorInterface $translator, ?TokenStorageInterface $tokenStorage, MenuFactory $menuFactory, CrudControllerRegistry $crudControllers, EntityFactory $entityFactory)
  37. {
  38. $this->cacheDir = $cacheDir;
  39. $this->translator = $translator;
  40. $this->tokenStorage = $tokenStorage;
  41. $this->menuFactory = $menuFactory;
  42. $this->crudControllers = $crudControllers;
  43. $this->entityFactory = $entityFactory;
  44. }
  45. public function create(Request $request, DashboardControllerInterface $dashboardController, ?CrudControllerInterface $crudController): AdminContext
  46. {
  47. $crudAction = $request->query->get(EA::CRUD_ACTION);
  48. $validPageNames = [Crud::PAGE_INDEX, Crud::PAGE_DETAIL, Crud::PAGE_EDIT, Crud::PAGE_NEW];
  49. $pageName = \in_array($crudAction, $validPageNames, true) ? $crudAction : null;
  50. $dashboardDto = $this->getDashboardDto($request, $dashboardController);
  51. $assetDto = $this->getAssetDto($dashboardController, $crudController);
  52. $actionConfigDto = $this->getActionConfig($dashboardController, $crudController, $pageName);
  53. $filters = $this->getFilters($dashboardController, $crudController);
  54. $crudDto = $this->getCrudDto($this->crudControllers, $dashboardController, $crudController, $actionConfigDto, $filters, $crudAction, $pageName);
  55. $entityDto = $this->getEntityDto($request, $crudDto);
  56. $searchDto = $this->getSearchDto($request, $crudDto);
  57. $i18nDto = $this->getI18nDto($request, $dashboardDto, $crudDto, $entityDto);
  58. $templateRegistry = $this->getTemplateRegistry($dashboardController, $crudDto);
  59. $user = $this->getUser($this->tokenStorage);
  60. return new AdminContext($request, $user, $i18nDto, $this->crudControllers, $dashboardDto, $dashboardController, $assetDto, $crudDto, $entityDto, $searchDto, $this->menuFactory, $templateRegistry);
  61. }
  62. private function getDashboardDto(Request $request, DashboardControllerInterface $dashboardControllerInstance): DashboardDto
  63. {
  64. $dashboardRoutesCachePath = $this->cacheDir.'/'.CacheWarmer::DASHBOARD_ROUTES_CACHE;
  65. $dashboardControllerRoutes = !file_exists($dashboardRoutesCachePath) ? [] : require $dashboardRoutesCachePath;
  66. $dashboardController = \get_class($dashboardControllerInstance).'::index';
  67. $dashboardRouteName = null;
  68. foreach ($dashboardControllerRoutes as $routeName => $controller) {
  69. if ($controller === $dashboardController) {
  70. // needed for i18n routes, whose name follows the pattern "route_name.locale"
  71. $dashboardRouteName = explode('.', $routeName, 2)[0];
  72. break;
  73. }
  74. }
  75. if (null === $dashboardRouteName) {
  76. throw new \RuntimeException(sprintf('The name of the route associated to "%s" cannot be determined. Clear the application cache to run the EasyAdmin cache warmer, which generates the needed data to find this route.', $dashboardController));
  77. }
  78. $dashboardDto = $dashboardControllerInstance->configureDashboard()->getAsDto();
  79. $dashboardDto->setRouteName($dashboardRouteName);
  80. return $dashboardDto;
  81. }
  82. private function getAssetDto(DashboardControllerInterface $dashboardController, ?CrudControllerInterface $crudController): AssetsDto
  83. {
  84. $defaultAssets = $dashboardController->configureAssets();
  85. if (null === $crudController) {
  86. return $defaultAssets->getAsDto();
  87. }
  88. return $crudController->configureAssets($defaultAssets)->getAsDto();
  89. }
  90. private function getCrudDto(CrudControllerRegistry $crudControllers, DashboardControllerInterface $dashboardController, ?CrudControllerInterface $crudController, ActionConfigDto $actionConfigDto, FilterConfigDto $filters, ?string $crudAction, ?string $pageName): ?CrudDto
  91. {
  92. if (null === $crudController) {
  93. return null;
  94. }
  95. $defaultCrud = $dashboardController->configureCrud();
  96. $crudDto = $crudController->configureCrud($defaultCrud)->getAsDto();
  97. $entityFqcn = $crudControllers->findEntityFqcnByCrudFqcn(\get_class($crudController));
  98. $crudDto->setControllerFqcn(\get_class($crudController));
  99. $crudDto->setActionsConfig($actionConfigDto);
  100. $crudDto->setFiltersConfig($filters);
  101. $crudDto->setCurrentAction($crudAction);
  102. $crudDto->setEntityFqcn($entityFqcn);
  103. $crudDto->setPageName($pageName);
  104. return $crudDto;
  105. }
  106. private function getActionConfig(DashboardControllerInterface $dashboardController, ?CrudControllerInterface $crudController, ?string $pageName): ActionConfigDto
  107. {
  108. if (null === $crudController) {
  109. return new ActionConfigDto();
  110. }
  111. $defaultActionConfig = $dashboardController->configureActions();
  112. return $crudController->configureActions($defaultActionConfig)->getAsDto($pageName);
  113. }
  114. private function getFilters(DashboardControllerInterface $dashboardController, ?CrudControllerInterface $crudController): FilterConfigDto
  115. {
  116. if (null === $crudController) {
  117. return new FilterConfigDto();
  118. }
  119. $defaultFilterConfig = $dashboardController->configureFilters();
  120. return $crudController->configureFilters($defaultFilterConfig)->getAsDto();
  121. }
  122. private function getTemplateRegistry(DashboardControllerInterface $dashboardController, ?CrudDto $crudDto): TemplateRegistry
  123. {
  124. $templateRegistry = TemplateRegistry::new();
  125. $defaultCrudDto = $dashboardController->configureCrud()->getAsDto();
  126. $templateRegistry->setTemplates($defaultCrudDto->getOverriddenTemplates());
  127. if (null !== $crudDto) {
  128. $templateRegistry->setTemplates($crudDto->getOverriddenTemplates());
  129. }
  130. return $templateRegistry;
  131. }
  132. private function getI18nDto(Request $request, DashboardDto $dashboardDto, ?CrudDto $crudDto, ?EntityDto $entityDto): I18nDto
  133. {
  134. $locale = $request->getLocale();
  135. $configuredTextDirection = $dashboardDto->getTextDirection();
  136. $localePrefix = strtolower(substr($locale, 0, 2));
  137. $defaultTextDirection = \in_array($localePrefix, ['ar', 'fa', 'he']) ? TextDirection::RTL : TextDirection::LTR;
  138. $textDirection = $configuredTextDirection ?? $defaultTextDirection;
  139. $translationDomain = $dashboardDto->getTranslationDomain();
  140. $translationParameters = [];
  141. if (null !== $crudDto) {
  142. $translationParameters['%entity_name%'] = $entityName = basename(str_replace('\\', '/', $crudDto->getEntityFqcn()));
  143. $translationParameters['%entity_as_string%'] = null === $entityDto ? '' : $entityDto->toString();
  144. $translationParameters['%entity_id%'] = $entityId = $request->query->get(EA::ENTITY_ID);
  145. $translationParameters['%entity_short_id%'] = null === $entityId ? null : u((string) $entityId)->truncate(7)->toString();
  146. $entityInstance = null === $entityDto ? null : $entityDto->getInstance();
  147. $pageName = $crudDto->getCurrentPage();
  148. $translatedSingularLabel = $this->translator->trans($crudDto->getEntityLabelInSingular($entityInstance, $pageName) ?? $entityName, $translationParameters, $translationDomain);
  149. $translatedPluralLabel = $this->translator->trans($crudDto->getEntityLabelInPlural($entityInstance, $pageName) ?? $entityName, $translationParameters, $translationDomain);
  150. $crudDto->setEntityLabelInSingular($translatedSingularLabel);
  151. $crudDto->setEntityLabelInPlural($translatedPluralLabel);
  152. $translationParameters['%entity_label_singular%'] = $translatedSingularLabel;
  153. $translationParameters['%entity_label_plural%'] = $translatedPluralLabel;
  154. }
  155. return new I18nDto($locale, $textDirection, $translationDomain, $translationParameters);
  156. }
  157. public function getSearchDto(Request $request, ?CrudDto $crudDto): ?SearchDto
  158. {
  159. if (null === $crudDto) {
  160. return null;
  161. }
  162. $queryParams = $request->query->all();
  163. $searchableProperties = $crudDto->getSearchFields();
  164. $query = $queryParams[EA::QUERY] ?? null;
  165. $defaultSort = $crudDto->getDefaultSort();
  166. $customSort = $queryParams[EA::SORT] ?? [];
  167. $appliedFilters = $queryParams[EA::FILTERS] ?? [];
  168. return new SearchDto($request, $searchableProperties, $query, $defaultSort, $customSort, $appliedFilters);
  169. }
  170. // Copied from https://github.com/symfony/twig-bridge/blob/master/AppVariable.php
  171. // (c) Fabien Potencier <fabien@symfony.com> - MIT License
  172. private function getUser(?TokenStorageInterface $tokenStorage): ?UserInterface
  173. {
  174. if (null === $tokenStorage || !$token = $tokenStorage->getToken()) {
  175. return null;
  176. }
  177. $user = $token->getUser();
  178. return \is_object($user) ? $user : null;
  179. }
  180. private function getEntityDto(Request $request, ?CrudDto $crudDto): ?EntityDto
  181. {
  182. if (null === $crudDto) {
  183. return null;
  184. }
  185. return $this->entityFactory->create($crudDto->getEntityFqcn(), $request->query->get(EA::ENTITY_ID), $crudDto->getEntityPermission());
  186. }
  187. }