diff --git a/.ddev/example/Controller/Admin/DashboardController.php b/.ddev/example/Controller/Admin/DashboardController.php index 56094ca0e5..385c67cf21 100644 --- a/.ddev/example/Controller/Admin/DashboardController.php +++ b/.ddev/example/Controller/Admin/DashboardController.php @@ -7,9 +7,8 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard; use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController; -use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; class DashboardController extends AbstractDashboardController { diff --git a/src/Router/AdminUrlGenerator.php b/src/Router/AdminUrlGenerator.php index 0e6b515f3d..4791dc809e 100644 --- a/src/Router/AdminUrlGenerator.php +++ b/src/Router/AdminUrlGenerator.php @@ -222,6 +222,8 @@ public function generateUrl(): string $this->initialize(); } + $usePrettyUrls = $this->adminRouteGenerator->usesPrettyUrls(); + if (true === $this->includeReferrer) { $this->setRouteParameter(EA::REFERRER, $this->customPageReferrer ?? $this->currentPageReferrer); } @@ -239,7 +241,9 @@ public function generateUrl(): string } $this->dashboardRoute = $dashboardRoute; - $this->unset(EA::DASHBOARD_CONTROLLER_FQCN); + if (!$usePrettyUrls) { + $this->unset(EA::DASHBOARD_CONTROLLER_FQCN); + } } // if the current action is 'index' and an entity ID is defined, remove the entity ID to prevent exceptions automatically @@ -276,7 +280,6 @@ public function generateUrl(): string } $context = $this->adminContextProvider->getContext(); - $usePrettyUrls = null !== $context && $context->usePrettyUrls(); $urlType = null !== $context && false === $context->getAbsoluteUrls() ? UrlGeneratorInterface::ABSOLUTE_PATH : UrlGeneratorInterface::ABSOLUTE_URL; if (null !== $this->get(EA::ROUTE_NAME)) { @@ -284,12 +287,15 @@ public function generateUrl(): string } if ($usePrettyUrls) { - $dashboardControllerFqcn = $this->get(EA::DASHBOARD_CONTROLLER_FQCN) ?? $context->getRequest()->attributes->get(EA::DASHBOARD_CONTROLLER_FQCN) ?? $this->dashboardControllerRegistry->getFirstDashboardFqcn(); - $crudControllerFqcn = $this->get(EA::CRUD_CONTROLLER_FQCN) ?? $context->getRequest()->attributes->get(EA::CRUD_CONTROLLER_FQCN); - $actionName = $this->get(EA::CRUD_ACTION) ?? $context->getRequest()->attributes->get(EA::CRUD_ACTION); + $dashboardControllerFqcn = $this->get(EA::DASHBOARD_CONTROLLER_FQCN) ?? $context?->getRequest()->attributes->get(EA::DASHBOARD_CONTROLLER_FQCN) ?? $this->dashboardControllerRegistry->getFirstDashboardFqcn(); + $crudControllerFqcn = $this->get(EA::CRUD_CONTROLLER_FQCN) ?? $context?->getRequest()->attributes->get(EA::CRUD_CONTROLLER_FQCN); + $actionName = $this->get(EA::CRUD_ACTION) ?? $context?->getRequest()->attributes->get(EA::CRUD_ACTION); if (null === $crudControllerFqcn || null === $routeName = $this->adminRouteGenerator->findRouteName($dashboardControllerFqcn, $crudControllerFqcn, $actionName)) { $routeName = $this->dashboardRoute; + if (null === $crudControllerFqcn) { + unset($routeParameters[EA::DASHBOARD_CONTROLLER_FQCN]); + } } else { // remove these parameters so they don't appear in the query string when using pretty URLs unset($routeParameters[EA::DASHBOARD_CONTROLLER_FQCN]); diff --git a/tests/Controller/CategoryCrudControllerTest.php b/tests/Controller/CategoryCrudControllerTest.php index 0affb5e5e4..d28adfeef9 100644 --- a/tests/Controller/CategoryCrudControllerTest.php +++ b/tests/Controller/CategoryCrudControllerTest.php @@ -208,8 +208,8 @@ public function testToggle(string $method, ?string $invalidCsrfToken, ?string $f $firstFoundToggleUrl = $crawler->filter('td.field-boolean .form-switch input[type="checkbox"]')->first()->attr('data-toggle-url'); // Get the category's active state from the DB - parse_str(parse_url($firstFoundToggleUrl, \PHP_URL_QUERY), $parameters); - $categoryId = $parameters['entityId']; + preg_match('#category/(\d+)/#', parse_url($firstFoundToggleUrl, \PHP_URL_PATH), $parameters); + $categoryId = $parameters[1] ?? null; $active = $this->categories->find($categoryId)->isActive(); static::assertIsBool($active); @@ -282,7 +282,7 @@ public function testPagination() // test pagination maintains all query parameters, including custom ones $queryParameters = http_build_query(['sort[name]' => 'DESC', 'CUSTOM_param' => 'foobar1234']); - $crawler = $this->client->request('GET', $this->generateIndexUrl().'&'.$queryParameters); + $crawler = $this->client->request('GET', $this->generateIndexUrl().'?'.$queryParameters); $firstPageUrl = $crawler->filter('.list-pagination-paginator .page-item:nth-child(2) .page-link')->attr('href'); static::assertSame(['name' => 'DESC'], $this->getParameterFromUrlQueryString($firstPageUrl, 'sort')); diff --git a/tests/Controller/Search/DefaultCrudSearchControllerTest.php b/tests/Controller/Search/DefaultCrudSearchControllerTest.php index 272c98d074..99b468c281 100644 --- a/tests/Controller/Search/DefaultCrudSearchControllerTest.php +++ b/tests/Controller/Search/DefaultCrudSearchControllerTest.php @@ -33,9 +33,6 @@ public function testDefaultEmptySearchForm() $this->assertSelectorNotExists('form.form-action-search .content-search-reset', 'The empty search form should not display the button to reset contents'); $form = $crawler->filter('form.form-action-search'); - $this->assertSame('index', $form->filter('input[type="hidden"][name="crudAction"]')->attr('value')); - $this->assertSame(DefaultCrudSearchController::class, $form->filter('input[type="hidden"][name="crudControllerFqcn"]')->attr('value')); - $this->assertSame('1', $form->filter('input[type="hidden"][name="page"]')->attr('value')); $formSearchInput = $form->filter('input[name="query"]'); $this->assertSame('', $formSearchInput->attr('value')); @@ -49,9 +46,6 @@ public function testSearchFormAfterMakingAQuery() $crawler = $this->client->request('GET', $this->generateIndexUrl('blog post')); $form = $crawler->filter('form.form-action-search'); - $this->assertSame('index', $form->filter('input[type="hidden"][name="crudAction"]')->attr('value')); - $this->assertSame(DefaultCrudSearchController::class, $form->filter('input[type="hidden"][name="crudControllerFqcn"]')->attr('value')); - $this->assertSame('1', $form->filter('input[type="hidden"][name="page"]')->attr('value')); $formSearchInput = $form->filter('input[name="query"]'); $this->assertSame('blog post', $formSearchInput->attr('value')); @@ -60,7 +54,8 @@ public function testSearchFormAfterMakingAQuery() $this->assertSame('off', $formSearchInput->attr('autocorrect')); $this->assertSelectorExists('form.form-action-search .content-search-reset', 'After making a query, the search form should display the button to reset contents'); - $this->assertSame($this->generateIndexUrl(), $crawler->filter('form.form-action-search .content-search-reset')->attr('href')); + // With prettyUrls, the generated URL contains the page parameter set to 1 + $this->assertSame($this->generateIndexUrl().'?page=1', $crawler->filter('form.form-action-search .content-search-reset')->attr('href')); } public function testPaginationNotDisplayedWhenNotNeeded() @@ -72,7 +67,6 @@ public function testPaginationNotDisplayedWhenNotNeeded() // assert that the pagination is not displayed because there are not enough results $form = $crawler->filter('form.form-action-search'); - $this->assertSame('1', $form->filter('input[type="hidden"][name="page"]')->attr('value')); $this->assertSame('1', $crawler->filter('.list-pagination .list-pagination-counter strong')->text()); $this->assertSelectorNotExists('.list-pagination nav.pager'); } @@ -90,7 +84,6 @@ public function testPaginationAndSortingIsResetAfterAQuery() // assert that the pagination and sorting is reset $form = $crawler->filter('form.form-action-search'); - $this->assertSame('1', $form->filter('input[type="hidden"][name="page"]')->attr('value')); $this->assertSame('1', $crawler->filter('.page-item.active .page-link')->text()); $this->assertCount(0, $crawler->filter('th[data-column="title"] a.sorted')); diff --git a/tests/Orm/BillSortTest.php b/tests/Orm/BillSortTest.php index bd340dd9dc..8608ba4c9d 100644 --- a/tests/Orm/BillSortTest.php +++ b/tests/Orm/BillSortTest.php @@ -53,7 +53,7 @@ public function testSorting(array $query, ?\Closure $sortFunction, string $expec } // Act - $crawler = $this->client->request('GET', $this->generateIndexUrl().'&'.http_build_query($query)); + $crawler = $this->client->request('GET', $this->generateIndexUrl().'?'.http_build_query($query)); // Assert $this->assertResponseIsSuccessful(); diff --git a/tests/Orm/CustomerSortTest.php b/tests/Orm/CustomerSortTest.php index d8f879faa4..b7a0611828 100644 --- a/tests/Orm/CustomerSortTest.php +++ b/tests/Orm/CustomerSortTest.php @@ -53,7 +53,7 @@ public function testSorting(array $query, ?\Closure $sortFunction, string $expec } // Act - $crawler = $this->client->request('GET', $this->generateIndexUrl().'&'.http_build_query($query)); + $crawler = $this->client->request('GET', $this->generateIndexUrl().'?'.http_build_query($query)); // Assert $this->assertResponseIsSuccessful(); diff --git a/tests/Orm/PageSortTest.php b/tests/Orm/PageSortTest.php index 39c18d2193..f7def584db 100644 --- a/tests/Orm/PageSortTest.php +++ b/tests/Orm/PageSortTest.php @@ -48,7 +48,7 @@ public function testSorting(array $query, ?string $sortFunction, string $expecte } // Act - $crawler = $this->client->request('GET', $this->generateIndexUrl().'&'.http_build_query($query)); + $crawler = $this->client->request('GET', $this->generateIndexUrl().'?'.http_build_query($query)); // Assert $this->assertResponseIsSuccessful(); diff --git a/tests/Orm/WebsiteSortTest.php b/tests/Orm/WebsiteSortTest.php index 47079676d1..2659c028a9 100644 --- a/tests/Orm/WebsiteSortTest.php +++ b/tests/Orm/WebsiteSortTest.php @@ -53,7 +53,7 @@ public function testSorting(array $query, ?\Closure $sortFunction, string $expec } // Act - $crawler = $this->client->request('GET', $this->generateIndexUrl().'&'.http_build_query($query)); + $crawler = $this->client->request('GET', $this->generateIndexUrl().'?'.http_build_query($query)); // Assert $this->assertResponseIsSuccessful(); diff --git a/tests/Router/AdminUrlGeneratorTest.php b/tests/Router/AdminUrlGeneratorTest.php index 2a91ae4b5a..78fc5aada9 100644 --- a/tests/Router/AdminUrlGeneratorTest.php +++ b/tests/Router/AdminUrlGeneratorTest.php @@ -10,6 +10,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteGenerator; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGeneratorInterface; +use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Controller\DashboardController; use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpFoundation\Request; @@ -303,11 +304,12 @@ private function getAdminUrlGenerator(bool $signedUrls = false, bool $absoluteUr ]); $dashboardControllerRegistry->method('getNumberOfDashboards')->willReturn(2); $dashboardControllerRegistry->method('getFirstDashboardRoute')->willReturn('admin'); + $dashboardControllerRegistry->method('getFirstDashboardFqcn')->willReturn(DashboardController::class); $container = Kernel::MAJOR_VERSION >= 6 ? static::getContainer() : self::$container; $router = $container->get('router'); - $adminRouteGenerator = $this->getMockBuilder(AdminRouteGenerator::class)->disableOriginalConstructor()->getMock(); + $adminRouteGenerator = $container->get(AdminRouteGenerator::class); return new AdminUrlGenerator($adminContextProvider, $router, $dashboardControllerRegistry, $adminRouteGenerator); } diff --git a/tests/TestApplication/config/routes.php b/tests/TestApplication/config/routes.php index 0c0249ffac..d003596652 100644 --- a/tests/TestApplication/config/routes.php +++ b/tests/TestApplication/config/routes.php @@ -5,4 +5,5 @@ return function (RoutingConfigurator $routes) { $routes->import('../src/Controller/', Kernel::MAJOR_VERSION >= 7 ? 'attribute' : 'annotation'); + $routes->import('.', 'easyadmin.routes'); }; diff --git a/tests/TestApplication/config/services.php b/tests/TestApplication/config/services.php index e4de14621f..32715923c2 100644 --- a/tests/TestApplication/config/services.php +++ b/tests/TestApplication/config/services.php @@ -2,6 +2,8 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; +use EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteGenerator; +use EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteLoader; use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\DataFixtures\AppFixtures; return static function (ContainerConfigurator $container) { @@ -20,4 +22,10 @@ ->tag('controller.service_arguments'); $services->set(AppFixtures::class)->tag('doctrine.fixture.orm'); + + $services + ->set(AdminRouteLoader::class) + ->arg(0, service(AdminRouteGenerator::class)) + ->tag('routing.loader', ['type' => AdminRouteLoader::ROUTE_LOADER_TYPE]) + ; }; diff --git a/tests/TestApplication/src/Controller/CategoryCrudController.php b/tests/TestApplication/src/Controller/CategoryCrudController.php index e9173f9e04..197daba7b5 100644 --- a/tests/TestApplication/src/Controller/CategoryCrudController.php +++ b/tests/TestApplication/src/Controller/CategoryCrudController.php @@ -2,6 +2,7 @@ namespace EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Controller; +use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminAction; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Assets; @@ -62,6 +63,7 @@ public function configureFilters(Filters $filters): Filters ->add('active'); } + #[AdminAction(routePath: '/customAction', routeName: 'custom_action')] public function customAction(AdminContext $context): Response { if (!$this->isGranted(Permission::EA_EXECUTE_ACTION, ['action' => AppAction::CUSTOM_ACTION, 'entity' => $context->getEntity()])) { diff --git a/tests/TestApplication/src/Controller/CustomHtmlAttributeDashboardController.php b/tests/TestApplication/src/Controller/CustomHtmlAttributeDashboardController.php index 9b33ed2729..337e90e4fe 100644 --- a/tests/TestApplication/src/Controller/CustomHtmlAttributeDashboardController.php +++ b/tests/TestApplication/src/Controller/CustomHtmlAttributeDashboardController.php @@ -8,7 +8,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Entity\BlogPost; use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Entity\Category; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; class CustomHtmlAttributeDashboardController extends AbstractDashboardController { diff --git a/tests/TestApplication/src/Controller/DashboardController.php b/tests/TestApplication/src/Controller/DashboardController.php index aa2eee8c4c..fbd0d66fde 100644 --- a/tests/TestApplication/src/Controller/DashboardController.php +++ b/tests/TestApplication/src/Controller/DashboardController.php @@ -8,7 +8,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Entity\BlogPost; use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Entity\Category; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; class DashboardController extends AbstractDashboardController { diff --git a/tests/TestApplication/src/Controller/ErrorDashboardController.php b/tests/TestApplication/src/Controller/ErrorDashboardController.php index 6b2839b6dc..691e126baa 100644 --- a/tests/TestApplication/src/Controller/ErrorDashboardController.php +++ b/tests/TestApplication/src/Controller/ErrorDashboardController.php @@ -6,7 +6,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; class ErrorDashboardController extends AbstractDashboardController { diff --git a/tests/TestApplication/src/Controller/SecureDashboardController.php b/tests/TestApplication/src/Controller/SecureDashboardController.php index 5ecff2c97e..0149cf0d43 100644 --- a/tests/TestApplication/src/Controller/SecureDashboardController.php +++ b/tests/TestApplication/src/Controller/SecureDashboardController.php @@ -8,7 +8,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Entity\BlogPost; use EasyCorp\Bundle\EasyAdminBundle\Tests\TestApplication\Entity\Category; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; class SecureDashboardController extends AbstractDashboardController {