You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR was squashed before being merged into the 4.x branch.
Discussion
----------
Update admin dashboard
When we moved to "pretty URLs", the recommended solution to define the dashboard route was this:
```php
// ...
use Symfony\Component\Routing\Attribute\Route;
class DashboardController extends AbstractDashboardController
{
#[Route('/admin', name: 'admin')]
public function index(): Response
{
return parent::index();
}
// ...
}
```
In the past weeks we've faced many issues related to the cache and the event listener related to admin URLs. The problem to solve is this: we need to find out very quickly (i.e. performant) and unequivocally if a given URLs belongs to an EasyAdmin backend or not.
When using pretty URLs, this is trivial because we generate those routes and apply some special route attributes to them. But, there's a missing route: the main dashboard route. That one is defined by the user and we cannot add those special attributes to it. Trust me, I tried this very hard (even asking internally to the Symfony Core Team). This is not possible technically speaking.
So, after thinking a lot about this, I propose to use the recently introduced `#[AdminDashboard]` attribute to define the admin route:
```php
use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminDashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[AdminDashboard(routePath: '/admin', routeName: 'admin')]
class DashboardController extends AbstractDashboardController
{
public function index(): Response
{
return parent::index();
}
// ...
}
```
This will solve all our problems, because this attribute will be used to generate the associated Symfony route. Since we create that route, we can apply the custom route attributes. This makes the caching hacks unnecessary and improves the performance of the application. So, I propose to add this now and make it mandatory in EasyAdmin 5.x as the only solution that works to define admin routes.
I know all these changes are tiring 😫 but this is the last time we'll change this and I think the change is worth it because it will solve all our internal issues related to admin routes 🙏
What do you think?
Commits
-------
901a892 Update admin dashboard
* @param string|null $routePath The path of the Symfony route that will be created for the dashboard (e.g. '/admin)
14
+
*/
15
+
public/* ?string */$routePath = null,
16
+
/**
17
+
* @param string|null $routeName The name of the Symfony route that will be created for the dashboard (e.g. 'admin')
18
+
*/
19
+
public/* ?string */$routeName = null,
20
+
/**
21
+
* @param array{
22
+
* requirements?: array,
23
+
* options?: array,
24
+
* defaults?: array,
25
+
* host?: string,
26
+
* methods?: array|string,
27
+
* schemes?: array|string,
28
+
* condition?: string,
29
+
* locale?: string,
30
+
* format?: string,
31
+
* utf8?: bool,
32
+
* stateless?: bool,
33
+
* } $routeOptions The configuration used when creating the Symfony route for the dashboard (these values are passed "as is" without any additional validation)
34
+
*/
35
+
publicarray$routeOptions = [],
36
+
/** @var array<string, array{routeName?: string, routePath?: string}>|null Allows to change the default route name and/or path of the CRUD actions for this dashboard */
13
37
public ?array$routes = null,
14
38
/** @var class-string[]|null $allowedControllers If defined, only these CRUD controllers will have a route defined for them */
15
39
public ?array$allowedControllers = null,
16
40
/** @var class-string[]|null $deniedControllers If defined, all CRUD controllers will have a route defined for them except these ones */
17
41
public ?array$deniedControllers = null,
18
42
) {
43
+
// when this attribute was first created, the $routes, $allowedControllers, and $deniedControllers
44
+
// were the first and only arguments of the class; now we added $routePath and $routeName as the
45
+
// first arguments, so we need to move the values of the old arguments to the new ones
46
+
if (\func_num_args() > 0 && \is_array(func_get_arg(0))) {
47
+
$this->routes = func_get_arg(0);
48
+
trigger_deprecation(
49
+
'easycorp/easyadmin-bundle',
50
+
'4.24.0',
51
+
'Passing $routes as the first argument of the "%s" attribute is deprecated and will no longer work in EasyAdmin 5.0.0. Pass the routes as the fourth argument or, better, use the \'routes:\' named argument.',
52
+
__CLASS__,
53
+
);
54
+
}
55
+
if (\func_num_args() > 1 && \is_array(func_get_arg(1))) {
56
+
$this->allowedControllers = func_get_arg(1);
57
+
trigger_deprecation(
58
+
'easycorp/easyadmin-bundle',
59
+
'4.24.0',
60
+
'Passing $allowedControllers as the second argument of the "%s" attribute is deprecated and will no longer work in EasyAdmin 5.0.0. Pass the allowed controllers as the fifth argument or, better, use the \'allowedControllers:\' named argument.',
'Passing $deniedControllers as the third argument of the "%s" attribute is deprecated and will no longer work in EasyAdmin 5.0.0. Pass the denied controllers as the sixth argument or, better, use the \'deniedControllers:\' named argument.',
'The "%s" dashboard controller applies the #[AdminDashboard] attribute, but it doesn\'t use it to define the route path and route name of the dashboard. Using the default #[Route] attribute from Symfony on the "index()" method of the dashboard instead of the #[AdminDashboard] attribute (e.g. #[AdminDashboard(routePath: \'/admin\', routeName: \'admin\')]) is deprecated and it will no longer work in EasyAdmin 5.0.0.',
259
+
$reflectionClass->getName()
260
+
);
261
+
}
262
+
} else {
263
+
@trigger_deprecation(
264
+
'easycorp/easyadmin-bundle',
265
+
'4.24.0',
266
+
'The "%s" dashboard controller does not apply the #[AdminDashboard] attribute. Applying this attribute is the recommended way to define the route path and route name of the dashboard, instead of using the default #[Route] attribute from Symfony (e.g. #[AdminDashboard(routePath: \'/admin\', routeName: \'admin\')]). Not applying the #[AdminDashboard] attribute is deprecated because it will be mandatory in EasyAdmin 5.0.0.',
267
+
$reflectionClass->getName()
268
+
);
269
+
}
270
+
271
+
// this is the legacy way to define the route configuration of the dashboard: using the Symfony #[Route]
272
+
// attribute on the "index()" method of the dashboard controller;
229
273
// for BC reasons, the Symfony Route attribute is available under two different namespaces;
230
274
// true first the recommended namespace and then fall back to the legacy namespace
thrownew \RuntimeException(sprintf('When using pretty URLs, the "%s" EasyAdmin dashboard controller must define its route configuration (route name and path) using Symfony\'s #[Route] attribute applied to its "index()" method.', $reflectionClass->getName()));
282
+
thrownew \RuntimeException(sprintf('When using pretty URLs, it\'s recommended to define the dashboard route name and path using the #[AdminDashboard] attribute on the dashboard class. Alternatively, you can apply Symfony\'s #[Route] attribute to the "index()" method of the "%s" controller. However, this alternative will no longer work in EasyAdmin 5.0.', $reflectionClass->getName()));
238
283
}
239
284
240
285
if (\count($attributes) > 1) {
241
-
thrownew \RuntimeException(sprintf('When using pretty URLs, the "%s" EasyAdmin dashboard controller must define only one #[Route] attribute applied on its "index()" method.', $reflectionClass->getName()));
286
+
thrownew \RuntimeException(sprintf('When using pretty URLs, it\'s recommended to define the dashboard route name and path using the #[AdminDashboard] attribute on the dashboard class. Alternatively, you can apply Symfony\'s #[Route] attribute to the "index()" method of the "%s" controller. In that case, you cannot apply more than one #[Route] attribute to the "index()" method. Also, this alternative will no longer work in EasyAdmin 5.0.', $reflectionClass->getName()));
242
287
}
243
288
244
289
$routeAttribute = $attributes[0]->newInstance();
@@ -349,6 +394,71 @@ private function getCustomActionsConfig(string $crudControllerFqcn): array
0 commit comments