diff --git a/app/src/Sonata/Admin/UserAdmin.php b/app/src/Sonata/Admin/UserAdmin.php index 032dc6ac..23745e41 100644 --- a/app/src/Sonata/Admin/UserAdmin.php +++ b/app/src/Sonata/Admin/UserAdmin.php @@ -213,7 +213,7 @@ 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), diff --git a/packages/sonata-extra-bundle/ActionableAdmin/AdminAction.php b/packages/sonata-extra-bundle/ActionableAdmin/AdminAction.php index a763bfe4..4fda2f8b 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,6 +23,10 @@ class AdminAction private string $urlSuffix; + private ?string $routePattern = null; + + private array $routeParams = []; + private string $access; private string|false|null $label; @@ -80,6 +85,30 @@ 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 getRouteParams(): array + { + return $this->routeParams; + } + + public function addRouteParam(string $key, mixed $value): self + { + $this->routeParams[$key] = $value; + + return $this; + } + public function getLabel(): bool|string|null { return $this->label; @@ -197,4 +226,11 @@ public function isForAction(string $action): bool { return $this->forActions[$action] ?? $this->forActions['_default']; } + + public function generateUrl(AdminInterface $admin, mixed $subject = null): string + { + return null !== $subject + ? $admin->generateObjectUrl($this->name, $subject, $this->routeParams) + : $admin->generateUrl($this->name, $this->routeParams); + } } 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..cc1738bf 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,8 @@
  • - + {% if item.action.icon %} {% endif %} {{ item.action|translate_label }} -
  • \ No newline at end of file + diff --git a/packages/sonata-extra-bundle/Resources/views/Action/list_action.html.twig b/packages/sonata-extra-bundle/Resources/views/Action/list_action.html.twig index 96f21305..57875341 100644 --- a/packages/sonata-extra-bundle/Resources/views/Action/list_action.html.twig +++ b/packages/sonata-extra-bundle/Resources/views/Action/list_action.html.twig @@ -1,8 +1,8 @@ {% if admin.hasAccess(actions.action.name, object) %} - + {% if actions.action.icon %} {% endif %} {{ actions.action|translate_label }} -{% endif %} \ No newline at end of file +{% endif %} diff --git a/packages/sonata-extra-bundle/Test/AdminTestHelperTrait.php b/packages/sonata-extra-bundle/Test/AdminTestHelperTrait.php new file mode 100644 index 00000000..e6562d04 --- /dev/null +++ b/packages/sonata-extra-bundle/Test/AdminTestHelperTrait.php @@ -0,0 +1,96 @@ +filter(\sprintf('.sonata-ba-list-field-actions[objectid="%s"]', $identifier)) + ->selectLink($action) + ->link() + ; + } + + protected function selectMenuObjectLink( + Crawler $crawler, + string $action, + ): Link { + return $crawler + ->filter('ul.dropdown-menu') + ->selectLink($action) + ->link() + ; + } + + protected function submitBatchAction( + KernelBrowser $client, + array $indexes, + string $action, + string $button = 'OK', + ): void { + $crawler = $client->submitForm( + $button, + [ + 'idx' => $indexes, + 'action' => $action, + ] + ); + + $client->submit( + $crawler->selectButton('Yes, execute')->form() + ); + } + + protected function appendDefaultFiltersToListUrl(string $listUrl): string + { + return \sprintf( + '%s%s%s', + $listUrl, + null === parse_url($listUrl, \PHP_URL_QUERY) ? '?' : '&', + http_build_query( + [ + 'filter' => [ + '_page' => 1, + '_per_page' => 25, + ], + ] + ) + ); + } + + protected function filterListByIdentifier( + KernelBrowser $client, + string $listUrl, + int|string $identifier, + string $identifierName = 'id', + ): Crawler { + return $client->request( + 'GET', + \sprintf( + '%s?%s', + $listUrl, + http_build_query( + [ + 'filter' => [ + $identifierName => [ + 'type' => 3, + 'value' => $identifier, + ], + ], + ] + ) + ) + ); + } +} diff --git a/packages/sonata-extra-bundle/composer.json b/packages/sonata-extra-bundle/composer.json index 1433eda5..f8c80ea9 100644 --- a/packages/sonata-extra-bundle/composer.json +++ b/packages/sonata-extra-bundle/composer.json @@ -10,6 +10,7 @@ "require": { "php": ">=8.2", "draw/dependency-injection": "^0.12", + "symfony/browser-kit": "^6.4.0", "symfony/framework-bundle": "^6.4.0", "symfony/expression-language": "^6.4.0", "symfony/string": "^6.4.0"