Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/Attribute/AdminRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ public function __construct(
* - [FooDashboard::class, BarDashboard::class, ...]: Deny specific dashboards
*/
public array|false|null $deniedDashboards = false,

/**
* @var string[]|null $allowedActions If defined at the class level, admin routes will be available only for the specified actions. Possible values:
* - null (default): Not set - allow all actions
* - [Action::INDEX, Action::DELETE, 'customAction', ...]: Allow only specific actions
*/
public ?array $allowedActions = null,

/**
* @var string[]|null $deniedActions If defined at the class level, admin routes won't be available for the specified actions. Possible values:
* - null (default): Not set - deny no actions
* - [Action::INDEX, Action::DELETE, 'customAction', ...]: Deny specific actions
*/
public ?array $deniedActions = null,
) {
}
}
18 changes: 16 additions & 2 deletions src/Router/AdminRouteGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@ private function generateAdminRoutes(): array

foreach (array_keys($actionsRouteConfig) as $actionName) {
$actionRouteConfig = $actionsRouteConfig[$actionName];

if (null !== $crudControllerRouteConfig['allowedActions'] && !\in_array($actionRouteConfig['actionName'], $crudControllerRouteConfig['allowedActions'], true)) {
continue;
}
if (null !== $crudControllerRouteConfig['deniedActions'] && \in_array($actionRouteConfig['actionName'], $crudControllerRouteConfig['deniedActions'], true)) {
continue;
}

$actionNameSnakeCase = strtolower(preg_replace('/[A-Z]/', '_$0', $actionRouteConfig['actionName']));
$actionNameSlug = strtolower(preg_replace('/[A-Z]/', '-$0', $actionRouteConfig['actionName']));

Expand Down Expand Up @@ -583,11 +591,11 @@ private function getDashboardsRouteConfig(): array
/**
* @param class-string<CrudControllerInterface> $crudControllerFqcn
*
* @return array{routeName: string, routePath: string}
* @return array{routeName: string, routePath: string, allowedActions: string[]|null, deniedActions: string[]|null}
*/
private function getCrudControllerRouteConfig(string $crudControllerFqcn): array
{
$crudControllerConfig = [];
$crudControllerConfig = ['allowedActions' => null, 'deniedActions' => null]; // Default to not set

$reflectionClass = new \ReflectionClass($crudControllerFqcn);

Expand All @@ -608,6 +616,12 @@ private function getCrudControllerRouteConfig(string $crudControllerFqcn): array

$crudControllerConfig['routeName'] = trim($adminRouteInstance->name, '_');
}

if (null !== $adminRouteInstance->allowedActions && null !== $adminRouteInstance->deniedActions) {
throw new \RuntimeException(sprintf('In the #[AdminRoute] attribute of the "%s" CRUD controller, you cannot define both "allowedActions" and "deniedActions" at the same time because they are the exact opposite. Use only one of them.', $crudControllerFqcn));
}
$crudControllerConfig['allowedActions'] = $adminRouteInstance->allowedActions;
$crudControllerConfig['deniedActions'] = $adminRouteInstance->deniedActions;
}

// if the CRUD controller doesn't define any or all of the route configuration,
Expand Down
Loading