diff --git a/app/src/Controller/Admin/SetPreferredLocaleAction.php b/app/src/Controller/Admin/SetPreferredLocaleAction.php new file mode 100644 index 00000000..ac4409f4 --- /dev/null +++ b/app/src/Controller/Admin/SetPreferredLocaleAction.php @@ -0,0 +1,28 @@ +execute( + static function (User $user) use ($request, $objectActionExecutioner): void { + $user->setPreferredLocale($request->get('_locale') ?? 'en'); + + $objectActionExecutioner->getAdmin()->update($user); + } + ); + } +} diff --git a/app/src/Sonata/Admin/UserAdmin.php b/app/src/Sonata/Admin/UserAdmin.php index 032dc6ac..074c4ac0 100644 --- a/app/src/Sonata/Admin/UserAdmin.php +++ b/app/src/Sonata/Admin/UserAdmin.php @@ -4,6 +4,7 @@ use App\Controller\Admin\AddRolesAminAction; use App\Controller\Admin\MakeAdminAction; +use App\Controller\Admin\SetPreferredLocaleAction; use App\Entity\Tag; use App\Entity\User; use Draw\Bundle\SonataExtraBundle\ActionableAdmin\ActionableAdminInterface; @@ -108,6 +109,7 @@ protected function configureShowFields(ShowMapper $show): void ->add('childObject2') ->add('email') ->add('dateOfBirth') + ->add('preferredLocale') ->add('roles', 'json') ->add('rolesList', 'list') ->add('static', 'static', ['virtual_field' => true, 'value' => 'Static value']) @@ -213,13 +215,32 @@ protected function configureFormFields(FormMapper $form): void public function getActions(): array { return [ - 'makeAdin' => (new AdminAction('makeAdmin', true)) + 'makeAdmin' => (new AdminAction('makeAdmin', true)) ->setController(MakeAdminAction::class) ->setIcon('fa fa-user-plus') ->setBatchController(MakeAdminAction::class), 'addRoles' => (new AdminAction('addRoles', true)) ->setController(AddRolesAminAction::class) ->setBatchController(AddRolesAminAction::class), + 'setPreferredLocale' => (new AdminAction('setPreferredLocale', true)) + ->setIcon('fa fa-language') + ->setController(SetPreferredLocaleAction::class) + ->setRoutePattern( + \sprintf( + '%s/preferred-locale/{_locale}', + $this->getRouterIdParameter(), + ) + ) + ->setActionsCallback( + static function (AdminAction $action): iterable { + foreach (['en', 'fr'] as $locale) { + yield (clone $action) + ->setLabel(strtoupper($locale)) + ->setRouteParameters(['_locale' => $locale]) + ; + } + } + ), ]; } } diff --git a/packages/sonata-extra-bundle/ActionableAdmin/AdminAction.php b/packages/sonata-extra-bundle/ActionableAdmin/AdminAction.php index a763bfe4..0e859739 100644 --- a/packages/sonata-extra-bundle/ActionableAdmin/AdminAction.php +++ b/packages/sonata-extra-bundle/ActionableAdmin/AdminAction.php @@ -2,6 +2,7 @@ namespace Draw\Bundle\SonataExtraBundle\ActionableAdmin; +use Sonata\AdminBundle\Admin\AdminInterface; use Symfony\Component\DependencyInjection\Attribute\Exclude; use Symfony\Component\String\UnicodeString; @@ -22,11 +23,20 @@ class AdminAction private string $urlSuffix; + private ?string $routePattern = null; + + private array $routeParameters = []; + private string $access; private string|false|null $label; private string|false|null $translationDomain = null; + /** + * @var callable + */ + private $actionsCallback; + public function __construct( private string $name, private bool $targetEntity, @@ -44,6 +54,8 @@ public function __construct( ->replace('_', '-') ->toString() ; + + $this->actionsCallback = fn () => [$this]; } public function getName(): string @@ -80,6 +92,18 @@ public function setUrlSuffix(string $urlSuffix): self return $this; } + public function getRoutePattern(): ?string + { + return $this->routePattern; + } + + public function setRoutePattern(?string $routePattern): self + { + $this->routePattern = $routePattern; + + return $this; + } + public function getLabel(): bool|string|null { return $this->label; @@ -197,4 +221,40 @@ public function isForAction(string $action): bool { return $this->forActions[$action] ?? $this->forActions['_default']; } + + public function getActions(): iterable + { + return \call_user_func($this->actionsCallback, $this); + } + + public function getActionsCallback(): callable + { + return $this->actionsCallback; + } + + public function setActionsCallback(callable $actionsCallback): self + { + $this->actionsCallback = $actionsCallback; + + return $this; + } + + public function getRouteParameters(): array + { + return $this->routeParameters; + } + + public function setRouteParameters(array $routeParameters): self + { + $this->routeParameters = $routeParameters; + + return $this; + } + + public function generateUrl(AdminInterface $admin, mixed $subject = null): string + { + return null !== $subject + ? $admin->generateObjectUrl($this->name, $subject, $this->routeParameters) + : $admin->generateUrl($this->name, $this->routeParameters); + } } diff --git a/packages/sonata-extra-bundle/ActionableAdmin/Extension/ActionableAdminExtension.php b/packages/sonata-extra-bundle/ActionableAdmin/Extension/ActionableAdminExtension.php index e66775ff..f67d429e 100644 --- a/packages/sonata-extra-bundle/ActionableAdmin/Extension/ActionableAdminExtension.php +++ b/packages/sonata-extra-bundle/ActionableAdmin/Extension/ActionableAdminExtension.php @@ -2,6 +2,7 @@ namespace Draw\Bundle\SonataExtraBundle\ActionableAdmin\Extension; +use Draw\Bundle\SonataExtraBundle\ActionableAdmin\AdminAction; use Draw\Bundle\SonataExtraBundle\ActionableAdmin\AdminActionLoader; use Sonata\AdminBundle\Admin\AbstractAdminExtension; use Sonata\AdminBundle\Admin\AdminInterface; @@ -36,14 +37,10 @@ public function configureRoutes(AdminInterface $admin, RouteCollectionInterface $defaults['_controller'] = $action->getController(); } - $pattern = $action->getTargetEntity() - ? $admin->getRouterIdParameter().'/'.$action->getUrlSuffix() - : $action->getUrlSuffix(); - $collection ->add( $action->getName(), - $pattern, + $this->getRoutePattern($admin, $action), defaults: $defaults ) ; @@ -144,4 +141,15 @@ public function configureActionButtons( return $list; } + + private function getRoutePattern(AdminInterface $admin, AdminAction $action): string + { + if (null !== $pattern = $action->getRoutePattern()) { + return $pattern; + } + + return $action->getTargetEntity() + ? \sprintf('%s/%s', $admin->getRouterIdParameter(), $action->getUrlSuffix()) + : $action->getUrlSuffix(); + } } diff --git a/packages/sonata-extra-bundle/Resources/views/Action/action.html.twig b/packages/sonata-extra-bundle/Resources/views/Action/action.html.twig index 462a4b6c..0e8f6f81 100644 --- a/packages/sonata-extra-bundle/Resources/views/Action/action.html.twig +++ b/packages/sonata-extra-bundle/Resources/views/Action/action.html.twig @@ -1,8 +1,10 @@ +{% for action in item.action.actions %}