Skip to content

Commit

Permalink
[SonataExtraBundle] BatchIterator for batch action
Browse files Browse the repository at this point in the history
  • Loading branch information
mpoiriert committed Aug 3, 2024
1 parent e0656b3 commit 2a22733
Show file tree
Hide file tree
Showing 12 changed files with 342 additions and 123 deletions.
65 changes: 47 additions & 18 deletions app/src/Controller/Admin/MakeAdminAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,61 @@

use App\Entity\User;
use App\Sonata\Admin\UserAdmin;
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\BatchActionInterface;
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\BatchIterator;
use Draw\Bundle\SonataExtraBundle\Notifier\Notification\SonataNotification;
use Sonata\AdminBundle\Admin\AdminInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Notifier\NotifierInterface;

class MakeAdminAction implements BatchActionInterface
class MakeAdminAction
{
public function __invoke(UserAdmin $admin, User $user): Response
public function __invoke(UserAdmin $admin, User $user, NotifierInterface $notifier): Response
{
$user->setRoles(
array_values(
array_unique(
array_merge(
$user->getRoles(),
['ROLE_ADMIN']
)
)
)
);

$admin->update($user);
if ($this->addAdminRole($user)) {
$admin->update($user);
$notifier->send(SonataNotification::success('User is now an admin'));
} else {
$notifier->send(
(new SonataNotification('User already has the admin role'))
->setSonataFlashType('info')
);
}

return new RedirectResponse($admin->generateUrl('list'));
return new RedirectResponse($admin->generateObjectUrl('show', $user));
}

public function getBatchCallable(): callable
private function addAdminRole(User $user): bool
{
return [$this, '__invoke'];
$currentRoles = $user->getRoles();

if (\in_array('ROLE_ADMIN', $currentRoles)) {
return false;
}

$user->setRoles([
...$currentRoles,
'ROLE_ADMIN',
]);

return true;
}

/**
* @param BatchIterator<User> $batchIterator
*/
public function batch(BatchIterator $batchIterator, AdminInterface $admin): Response
{
foreach ($batchIterator->getObjects() as $object) {
if (!$this->addAdminRole($object)) {
$batchIterator->skip('already-admin');

continue;
}

$admin->update($object);
}

return new RedirectResponse($admin->generateUrl('list'));
}
}
2 changes: 1 addition & 1 deletion app/src/Sonata/Admin/UserAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,6 @@ public function getActions(): iterable
yield (new AdminAction('makeAdmin', true))
->setController(MakeAdminAction::class)
->setIcon('fa fa-user-plus')
->setAllowBatchAction(true);
->setBatchController(MakeAdminAction::class.'::batch');
}
}

This file was deleted.

42 changes: 23 additions & 19 deletions packages/sonata-extra-bundle/ActionableAdmin/AdminAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Draw\Bundle\SonataExtraBundle\ActionableAdmin;

use Draw\Bundle\SonataExtraBundle\ActionableAdmin\Action\BatchAction;
use Symfony\Component\DependencyInjection\Attribute\Exclude;
use Symfony\Component\String\UnicodeString;

Expand All @@ -15,14 +14,14 @@ class AdminAction
'_default' => true,
];

private bool $allowBatchAction = false;
private ?string $controller = null;

private mixed $controller = null;

private string $batchController = BatchAction::class;
private ?string $batchController = null;

private ?string $icon = null;

private string $urlSuffix;

private string $access;

private string|false|null $label;
Expand All @@ -38,6 +37,11 @@ public function __construct(
->snake()
->upper()
->toString();

$this->urlSuffix = (new UnicodeString($this->name))
->snake()
->replace('_', '-')
->toString();
}

public function getName(): string
Expand All @@ -62,6 +66,18 @@ public function setAccess(string $access): self
return $this;
}

public function getUrlSuffix(): string
{
return $this->urlSuffix;
}

public function setUrlSuffix(string $urlSuffix): self
{
$this->urlSuffix = $urlSuffix;

return $this;
}

public function getLabel(): bool|string|null
{
return $this->label;
Expand All @@ -86,12 +102,12 @@ public function setTranslationDomain(bool|string|null $translationDomain): self
return $this;
}

public function getController(): mixed
public function getController(): string
{
return $this->controller;
}

public function setController(mixed $controller): self
public function setController(string $controller): self
{
$this->controller = $controller;

Expand Down Expand Up @@ -122,18 +138,6 @@ public function setIcon(?string $icon): self
return $this;
}

public function getAllowBatchAction(): bool
{
return $this->allowBatchAction;
}

public function setAllowBatchAction(bool $allowBatchAction): self
{
$this->allowBatchAction = $allowBatchAction;

return $this;
}

public function getForEntityListAction(): bool
{
return $this->forEntityListAction;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Draw\Bundle\SonataExtraBundle\ActionableAdmin\ArgumentResolver;

use Draw\Bundle\SonataExtraBundle\ActionableAdmin\BatchIterator;
use Sonata\AdminBundle\Request\AdminFetcherInterface;
use Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;

class BatchIteratorValueResolver implements ValueResolverInterface
{
public function __construct(
private AdminFetcherInterface $adminFetcher,
private BatchIterator $batchIterator
) {
}

public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
$type = $argument->getType();

if (null === $type) {
return [];
}

if (BatchIterator::class !== $type && !is_subclass_of($type, BatchIterator::class)) {
return [];
}

try {
$admin = $this->adminFetcher->get($request);
} catch (\InvalidArgumentException) {
return [];
}

$action = $request->request->get('action');

if (null === $action) {
return [];
}

foreach ($request->attributes as $attribute) {
if ($attribute instanceof ProxyQuery) {
return [$this->batchIterator->initialize(
query: $attribute,
admin: $admin,
action: $action,
)];
}
}

return [];
}
}

This file was deleted.

Loading

0 comments on commit 2a22733

Please sign in to comment.