Skip to content

Commit

Permalink
[SonataExtraBundle] GenericFormHandler for both batch and entity cust…
Browse files Browse the repository at this point in the history
…om form
  • Loading branch information
mpoiriert committed Aug 9, 2024
1 parent 3616922 commit 9d8f951
Show file tree
Hide file tree
Showing 13 changed files with 359 additions and 63 deletions.
39 changes: 39 additions & 0 deletions app/src/Controller/Admin/AddRolesAminAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace App\Controller\Admin;

use App\Entity\User;
use App\Form\AddRolesForm;
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\GenericFormHandler;
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\ObjectActionExecutioner;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class AddRolesAminAction
{
public function __invoke(
ObjectActionExecutioner $objectActionExecutioner,
Request $request,
GenericFormHandler $genericFormHandler
): Response {
return $genericFormHandler
->execute(
$objectActionExecutioner,
$request,
AddRolesForm::class,
null,
function (User $user, array $data) use ($objectActionExecutioner): void {
$roles = $data['roles'];

$missingRoles = array_diff($roles, $user->getRoles());

if (\count($missingRoles) > 0) {
$user->setRoles(array_merge($user->getRoles(), $missingRoles));
$objectActionExecutioner->getAdmin()->update($user);
} else {
$objectActionExecutioner->skip('all-roles-already-set');
}
}
);
}
}
4 changes: 1 addition & 3 deletions app/src/Controller/Admin/MakeAdminAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\Event\ExecutionErrorEvent;
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\ObjectActionExecutioner;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Notifier\NotifierInterface;

class MakeAdminAction
{
public function __invoke(
ObjectActionExecutioner $objectActionExecutioner,
NotifierInterface $notifier
ObjectActionExecutioner $objectActionExecutioner
): Response {
return $objectActionExecutioner
->execute(
Expand Down
7 changes: 6 additions & 1 deletion app/src/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,12 @@ public function getRoles(): array

public function setRoles(array $roles): static
{
$this->roles = $roles;
$this->roles = array_values(
array_filter(
$roles,
fn ($role) => \is_string($role) && '' !== $role && 'ROLE_USER' !== $role
)
);

return $this;
}
Expand Down
33 changes: 33 additions & 0 deletions app/src/Form/AddRolesForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;

class AddRolesForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add(
'roles',
ChoiceType::class,
[
'choices' => [
'ROLE_ADMIN' => 'ROLE_ADMIN',
'ROLE_USER' => 'ROLE_USER',
],
'multiple' => true,
'expanded' => true,
]
)
->add(
'submit',
SubmitType::class,
['label' => 'submit']
);
}
}
5 changes: 5 additions & 0 deletions app/src/Sonata/Admin/UserAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Sonata\Admin;

use App\Controller\Admin\AddRolesAminAction;
use App\Controller\Admin\MakeAdminAction;
use App\Entity\Tag;
use App\Entity\User;
Expand Down Expand Up @@ -83,6 +84,7 @@ protected function configureListFields(ListMapper $list): void
->add('childObject2')
->add('userTags', 'list')
->add('tags', 'list')
->add('roles', 'list')
->add('isLocked', 'boolean', ['inverse' => true]);
}

Expand Down Expand Up @@ -209,6 +211,9 @@ public function getActions(): array
->setController(MakeAdminAction::class)
->setIcon('fa fa-user-plus')
->setBatchController(MakeAdminAction::class),
'addRoles' => (new AdminAction('addRoles', true))
->setController(AddRolesAminAction::class)
->setBatchController(AddRolesAminAction::class),
];
}
}
43 changes: 43 additions & 0 deletions packages/sonata-extra-bundle/ActionableAdmin/AdminActionLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Draw\Bundle\SonataExtraBundle\ActionableAdmin;

use Draw\Bundle\SonataExtraBundle\ActionableAdmin\Extension\ActionableAdminExtensionInterface;
use Sonata\AdminBundle\Admin\AdminInterface;

class AdminActionLoader
{
private array $actions = [];

/**
* @return array<string,AdminAction>
*/
public function getActions(AdminInterface $admin): array
{
if (!\array_key_exists($admin->getCode(), $this->actions)) {
$actions = $admin instanceof ActionableAdminInterface
? $admin->getActions()
: [];

foreach ($admin->getExtensions() as $extension) {
if (!$extension instanceof ActionableAdminExtensionInterface) {
continue;
}

$actions = $extension->getActions($actions);
}

array_walk(
$actions,
function (AdminAction $adminAction) use ($admin): void {
// Set default translation domain
$adminAction->setTranslationDomain($adminAction->getTranslationDomain() ?? $admin->getTranslationDomain());
}
);

$this->actions[$admin->getCode()] = $actions;
}

return $this->actions[$admin->getCode()];
}
}
29 changes: 14 additions & 15 deletions packages/sonata-extra-bundle/ActionableAdmin/ExecutionNotifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ class ExecutionNotifier implements ResetInterface

public function __construct(
private ?NotifierInterface $notifier,
private TranslatorInterface $translator
private TranslatorInterface $translator,
private AdminActionLoader $actionLoader,
) {
}

Expand All @@ -32,9 +33,9 @@ public function notifyExecution(ObjectActionExecutioner $objectActionExecutioner
),
];

if ($objectActionExecutioner->isBatch()) {
$count = $objectActionExecutioner->getProcessedCount();
$count = $objectActionExecutioner->getProcessedCount();

if ($objectActionExecutioner->isBatch() || $count > 0) {
$subject = $this->translator
->trans(
'execution.notification.processed',
Expand Down Expand Up @@ -115,19 +116,17 @@ private function getActionLabel(AdminInterface $admin, string $action): string

if (!isset($this->actionLabels[$adminCode][$action])) {
$label = null;
if ($admin instanceof ActionableAdminInterface) {
foreach ($admin->getActions() as $adminAction) {
if ($adminAction->getName() === $action) {
$label = $this->translator
->trans(
$adminAction->getLabel(),
[],
$adminAction->getTranslationDomain()
);
break;
}
}
$adminAction = $this->actionLoader->getActions($admin)[$action] ?? null;

if ($adminAction instanceof AdminAction) {
$label = $this->translator
->trans(
$adminAction->getLabel(),
[],
$adminAction->getTranslationDomain()
);
}

$label ??= $action;

$this->actionLabels[$adminCode][$action] = $label;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

namespace Draw\Bundle\SonataExtraBundle\ActionableAdmin\Extension;

use Draw\Bundle\SonataExtraBundle\ActionableAdmin\ActionableAdminInterface;
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\AdminAction;
use Draw\Bundle\SonataExtraBundle\ActionableAdmin\AdminActionLoader;
use Sonata\AdminBundle\Admin\AbstractAdminExtension;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Datagrid\ListMapper;
Expand All @@ -19,11 +18,14 @@
)]
class ActionableAdminExtension extends AbstractAdminExtension
{
private array $actions = [];
public function __construct(
private AdminActionLoader $actionLoader
) {
}

public function configureRoutes(AdminInterface $admin, RouteCollectionInterface $collection): void
{
foreach ($this->loadActions($admin) as $action) {
foreach ($this->actionLoader->getActions($admin) as $action) {
$defaults = [
'_actionableAdmin' => [
'action' => $action->getName(),
Expand Down Expand Up @@ -51,7 +53,7 @@ public function getAccessMapping(AdminInterface $admin): array
{
$accessMapping = [];

foreach ($this->loadActions($admin) as $adminAction) {
foreach ($this->actionLoader->getActions($admin) as $adminAction) {
$accessMapping[$adminAction->getName()] = $adminAction->getAccess();
}

Expand All @@ -60,7 +62,7 @@ public function getAccessMapping(AdminInterface $admin): array

public function configureBatchActions(AdminInterface $admin, array $actions): array
{
foreach ($this->loadActions($admin) as $adminAction) {
foreach ($this->actionLoader->getActions($admin) as $adminAction) {
if (!$batchController = $adminAction->getBatchController()) {
continue;
}
Expand All @@ -81,7 +83,7 @@ public function configureBatchActions(AdminInterface $admin, array $actions): ar

public function configureListFields(ListMapper $list): void
{
foreach ($this->loadActions($list->getAdmin()) as $adminAction) {
foreach ($this->actionLoader->getActions($list->getAdmin()) as $adminAction) {
if (!$adminAction->getForEntityListAction()) {
continue;
}
Expand Down Expand Up @@ -115,7 +117,7 @@ public function configureActionButtons(
string $action,
?object $object = null
): array {
foreach ($this->loadActions($admin) as $adminAction) {
foreach ($this->actionLoader->getActions($admin) as $adminAction) {
if (!$adminAction->isForAction($action)) {
continue;
}
Expand All @@ -141,36 +143,4 @@ public function configureActionButtons(

return $list;
}

/**
* @return array<AdminAction>
*/
private function loadActions(AdminInterface $admin): array
{
if (!\array_key_exists($admin->getCode(), $this->actions)) {
$actions = $admin instanceof ActionableAdminInterface
? $admin->getActions()
: [];

foreach ($admin->getExtensions() as $extension) {
if (!$extension instanceof ActionableAdminExtensionInterface) {
continue;
}

$actions = $extension->getActions($actions);
}

array_walk(
$actions,
function (AdminAction $adminAction) use ($admin): void {
// Set default translation domain
$adminAction->setTranslationDomain($adminAction->getTranslationDomain() ?? $admin->getTranslationDomain());
}
);

$this->actions[$admin->getCode()] = $actions;
}

return $this->actions[$admin->getCode()];
}
}
Loading

0 comments on commit 9d8f951

Please sign in to comment.