diff --git a/src/Access/AccessService.php b/src/Access/AccessService.php index 56fc594f..5adcbca8 100644 --- a/src/Access/AccessService.php +++ b/src/Access/AccessService.php @@ -777,4 +777,19 @@ public function getBasicRoles(): array return array_map([$this, 'wrapUserRole'], $roles); } + + /** + * @return array + */ + public function getSelectableRoles(): array + { + return $this->app->config('access.selectable_roles') ?: []; + } + + public function canSelectUserRoles(): bool + { + $roles = $this->getSelectableRoles(); + + return $roles !== [] && $this->check(static::ROLE_MODIFY_ACTION); + } } diff --git a/src/Field/UserRoleListField.php b/src/Field/UserRoleListField.php new file mode 100644 index 00000000..d4db4900 --- /dev/null +++ b/src/Field/UserRoleListField.php @@ -0,0 +1,53 @@ +accessService->getSelectableRoles(); + + $options = []; + + $iAmSuperUser = $this->accessService->isSuperUser(); + + foreach ($roles as $value => $text) { + if ($text instanceof EnumTranslatableInterface || is_numeric($value)) { + $value = value($text); + $text = $this->accessService->wrapUserRole($value)?->getTitle() ?? $value; + } + + if (!$iAmSuperUser && $this->accessService->isSuperUserRole($value)) { + continue; + } + + $options[] = static::createOption($text, (string) $value); + } + + return $options; + } + + /** + * @return array + */ + protected function getAccessors(): array + { + return array_merge( + parent::getAccessors(), + [] + ); + } +} diff --git a/src/LunaPackage.php b/src/LunaPackage.php index 946c2efd..df72cfe1 100644 --- a/src/LunaPackage.php +++ b/src/LunaPackage.php @@ -62,6 +62,49 @@ public function __construct(public ApplicationInterface $app) { } + public function getLoginName(): string + { + return $this->app->config('user.login_name') ?? 'username'; + } + + public function isAdmin(): bool + { + if ($this->app instanceof WebApplicationInterface) { + return $this->app->service(AppRequest::class)->getMatchedRoute()?->getExtraValue('namespace') === 'admin'; + } + + return false; + } + + public function isFront(): bool + { + if ($this->app instanceof WebApplicationInterface) { + return $this->app->service(AppRequest::class)->getMatchedRoute()?->getExtraValue('namespace') === 'front'; + } + + return false; + } + + public function bootBeforeRequest(Container $container): void + { + // Error + if (!$this->app->isDebug() && $this->app->getClient() === AppClient::WEB) { + $errorService = $container->get(ErrorService::class); + + $errorService->addHandler( + $container->newInstance( + LunaErrorHandler::class, + [ + 'layout' => $this->app->config('luna.error.layout') ?? 'error', + 'route' => $this->app->config('luna.error.route') ?? 'front::home', + ] + ), + 'default' + ); + $errorService->register(); + } + } + public function register(Container $container): void { $container->share(static::class, $this); @@ -130,49 +173,6 @@ public function register(Container $container): void ); } - public function getLoginName(): string - { - return $this->app->config('user.login_name') ?? 'username'; - } - - public function isAdmin(): bool - { - if ($this->app instanceof WebApplicationInterface) { - return $this->app->service(AppRequest::class)->getMatchedRoute()?->getExtraValue('namespace') === 'admin'; - } - - return false; - } - - public function isFront(): bool - { - if ($this->app instanceof WebApplicationInterface) { - return $this->app->service(AppRequest::class)->getMatchedRoute()?->getExtraValue('namespace') === 'front'; - } - - return false; - } - - public function bootBeforeRequest(Container $container): void - { - // Error - if (!$this->app->isDebug() && $this->app->getClient() === AppClient::WEB) { - $errorService = $container->get(ErrorService::class); - - $errorService->addHandler( - $container->newInstance( - LunaErrorHandler::class, - [ - 'layout' => $this->app->config('luna.error.layout') ?? 'error', - 'route' => $this->app->config('luna.error.route') ?? 'front::home', - ] - ), - 'default' - ); - $errorService->register(); - } - } - protected function registerFaker(Container $container) { if ($container->has(FakerService::class)) { diff --git a/src/Module/Admin/User/Form/EditForm.php b/src/Module/Admin/User/Form/EditForm.php index 5632d55f..55b1d158 100644 --- a/src/Module/Admin/User/Form/EditForm.php +++ b/src/Module/Admin/User/Form/EditForm.php @@ -6,6 +6,7 @@ use Lyrasoft\Luna\Access\AccessService; use Lyrasoft\Luna\Auth\SRP\SRPService; +use Lyrasoft\Luna\Field\UserRoleListField; use Lyrasoft\Luna\LunaPackage; use Unicorn\Field\CalendarField; use Unicorn\Field\SingleImageDragField; @@ -14,14 +15,10 @@ use Windwalker\Filter\Rule\EmailAddress; use Windwalker\Form\Field\EmailField; use Windwalker\Form\Field\HiddenField; -use Windwalker\Form\Field\ListField; use Windwalker\Form\Field\PasswordField; use Windwalker\Form\Field\TextField; use Windwalker\Form\FieldDefinitionInterface; use Windwalker\Form\Form; -use Windwalker\Utilities\Enum\EnumTranslatableInterface; - -use function Windwalker\value; /** * The EditForm class. @@ -105,29 +102,9 @@ function (Form $form) { ->width(400) ->height(400); - $roles = $this->luna->app->config('access.selectable_roles') ?: []; - - if ($roles && $this->accessService->check(AccessService::ROLE_MODIFY_ACTION)) { - $iAmSuperUser = $this->accessService->isSuperUser(); - - $form->add('roles', ListField::class) + if ($this->accessService->canSelectUserRoles()) { + $form->add('roles', UserRoleListField::class) ->label($this->trans('luna.user.field.roles')) - // ->required(true) - ->registerOptions( - $roles, - function (ListField $field, mixed $text, mixed $value) use ($iAmSuperUser) { - if ($text instanceof EnumTranslatableInterface || is_numeric($value)) { - $value = value($text); - $text = $this->accessService->wrapUserRole($value)?->getTitle() ?? $value; - } - - if (!$iAmSuperUser && $this->accessService->isSuperUserRole($value)) { - return; - } - - $field->option($text, (string) $value); - } - ) ->multiple(true) ->addClass('has-tom-select'); }