Skip to content

Commit

Permalink
Autoinject all admin variables
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Oct 10, 2023
1 parent eed8f63 commit 8f51141
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/Controller/CRUDController.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ public function listAction(Request $request): Response
$exportFormats = $exporter->getAvailableFormats($this->admin);
}

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'list',
'form' => $formView,
Expand Down Expand Up @@ -262,6 +265,9 @@ public function deleteAction(Request $request): Response

$template = $this->templateRegistry->getTemplate('delete');

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'object' => $object,
'action' => 'delete',
Expand Down Expand Up @@ -371,6 +377,9 @@ public function editAction(Request $request): Response

$template = $this->templateRegistry->getTemplate($templateKey);

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'edit',
'form' => $formView,
Expand Down Expand Up @@ -491,6 +500,9 @@ public function batchAction(Request $request): Response

$template = $batchAction['template'] ?? $this->templateRegistry->getTemplate('batch_confirmation');

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'list',
'action_label' => $actionLabel,
Expand Down Expand Up @@ -544,6 +556,9 @@ public function createAction(Request $request): Response
$class = new \ReflectionClass($this->admin->hasActiveSubClass() ? $this->admin->getActiveSubClass() : $this->admin->getClass());

if ($class->isAbstract()) {
/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams(
'@SonataAdmin/CRUD/select_subclass.html.twig',
[
Expand Down Expand Up @@ -632,6 +647,9 @@ public function createAction(Request $request): Response

$template = $this->templateRegistry->getTemplate($templateKey);

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'create',
'form' => $formView,
Expand Down Expand Up @@ -664,6 +682,9 @@ public function showAction(Request $request): Response

$template = $this->templateRegistry->getTemplate('show');

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'show',
'object' => $object,
Expand Down Expand Up @@ -702,6 +723,9 @@ public function historyAction(Request $request): Response

$template = $this->templateRegistry->getTemplate('history');

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'history',
'object' => $object,
Expand Down Expand Up @@ -753,6 +777,9 @@ public function historyViewRevisionAction(Request $request, string $revision): R

$template = $this->templateRegistry->getTemplate('show');

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'show',
'object' => $object,
Expand Down Expand Up @@ -813,6 +840,9 @@ public function historyCompareRevisionsAction(Request $request, string $baseRevi

$template = $this->templateRegistry->getTemplate('show_compare');

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'show',
'object' => $baseObject,
Expand Down Expand Up @@ -921,6 +951,9 @@ public function aclAction(Request $request): Response

$template = $this->templateRegistry->getTemplate('acl');

/**
* @psalm-suppress DeprecatedMethod
*/
return $this->renderWithExtraParams($template, [
'action' => 'acl',
'permissions' => $adminObjectAclData->getUserPermissions(),
Expand Down Expand Up @@ -961,16 +994,27 @@ final public function configureAdmin(Request $request): void
*
* @param string $view The view name
* @param array<string, mixed> $parameters An array of parameters to pass to the view
*
* @deprecated since sonata-project/admin-bundle version 4.x
*
* NEXT_MAJOR: Remove this method
*/
final protected function renderWithExtraParams(string $view, array $parameters = [], ?Response $response = null): Response
{
/**
* @psalm-suppress DeprecatedMethod
*/
return $this->render($view, $this->addRenderExtraParams($parameters), $response);
}

/**
* @param array<string, mixed> $parameters
*
* @return array<string, mixed>
*
* @deprecated since sonata-project/admin-bundle version 4.x
*
* NEXT_MAJOR: Remove this method
*/
protected function addRenderExtraParams(array $parameters = []): array
{
Expand Down Expand Up @@ -1020,6 +1064,10 @@ protected function getLogger(): LoggerInterface
* Returns the base template name.
*
* @return string The template name
*
* @deprecated since sonata-project/admin-bundle version 4.x
*
* NEXT_MAJOR: Remove this method
*/
protected function getBaseTemplate(): string
{
Expand Down
83 changes: 83 additions & 0 deletions src/EventListener/AdminEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\AdminBundle\EventListener;

use Sonata\AdminBundle\Request\AdminFetcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;

/**
* @author Christian Gripp <mail@core23.de>
*/
final class AdminEventListener implements EventSubscriberInterface
{
public function __construct(private Environment $twig, private AdminFetcherInterface $adminFetcher)
{
}

public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => [['onKernelRequest', -50]],
];
}

public function onKernelRequest(KernelEvent $event): void
{
$request = $event->getRequest();

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

$this->addVariable('admin', $admin);

$templateRegistry = $admin->getTemplateRegistry();

if ($this->isXmlHttpRequest($request)) {
$baseTemplate = $templateRegistry->getTemplate('ajax');
} else {
$baseTemplate = $templateRegistry->getTemplate('layout');
}

$this->addVariable('base_template', $baseTemplate);
}

/**
* Returns true if the request is a XMLHttpRequest.
*
* @return bool True if the request is an XMLHttpRequest, false otherwise
*/
private function isXmlHttpRequest(Request $request): bool
{
if ($request->isXmlHttpRequest()) {
return true;
}

return null !== $request->attributes->get('_xml_http_request');
}

private function addVariable(string $name, mixed $value): void
{
try {
$this->twig->addGlobal($name, $value);
} catch (\LogicException) {
}
}
}
8 changes: 8 additions & 0 deletions src/Resources/config/event_listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Sonata\AdminBundle\EventListener\AdminEventListener;
use Sonata\AdminBundle\EventListener\ConfigureCRUDControllerListener;

return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->services()

->set('sonata.admin.event_listener.admin_event', AdminEventListener::class)
->tag('kernel.event_subscriber')
->args([
new ReferenceConfigurator('twig'),
new ReferenceConfigurator('sonata.admin.request.fetcher'),
])

->set('sonata.admin.event_listener.configure_crud_controller', ConfigureCRUDControllerListener::class)
->tag('kernel.event_subscriber');
};
107 changes: 107 additions & 0 deletions tests/EventListener/AdminEventListenerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\AdminBundle\Tests\EventListener;

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\EventListener\AdminEventListener;
use Sonata\AdminBundle\Request\AdminFetcherInterface;
use Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;
use Twig\Loader\ArrayLoader;

final class AdminEventListenerTest extends TestCase
{
private Environment $twig;

/**
* @var AdminFetcherInterface&MockObject
*/
private AdminFetcherInterface $adminFetcher;

private AdminEventListener $listener;

protected function setUp(): void
{
$this->twig = new Environment(new ArrayLoader([
]));
$this->adminFetcher = $this->createMock(AdminFetcherInterface::class);

$this->listener = new AdminEventListener(
$this->twig,
$this->adminFetcher
);
}

public function testGetSubscribedEvents(): void
{
static::assertSame([
KernelEvents::REQUEST => [['onKernelRequest', -50]],
], AdminEventListener::getSubscribedEvents());
}

public function testOnKernelRequest(): void
{
$request = new Request();

$event = new KernelEvent(self::createStub(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST);

$admin = self::createStub(AdminInterface::class);

$this->adminFetcher->method('get')->willReturn($admin);

$templateRegistry = $this->createMock(MutableTemplateRegistryInterface::class);
$templateRegistry->expects(static::once())->method('getTemplate')->with('layout')
->willReturn('layout.html.twig');

$admin->method('getTemplateRegistry')->willReturn($templateRegistry);

$this->listener->onKernelRequest($event);

$global = $this->twig->getGlobals();

static::assertSame($admin, $global['admin']);
static::assertSame('layout.html.twig', $global['base_template']);
}

public function testOnAjaxKernelRequest(): void
{
$request = new Request();
$request->attributes->set('_xml_http_request', true);

$event = new KernelEvent(self::createStub(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST);

$admin = self::createStub(AdminInterface::class);

$this->adminFetcher->method('get')->willReturn($admin);

$templateRegistry = $this->createMock(MutableTemplateRegistryInterface::class);
$templateRegistry->expects(static::once())->method('getTemplate')->with('ajax')
->willReturn('ajax.html.twig');

$admin->method('getTemplateRegistry')->willReturn($templateRegistry);

$this->listener->onKernelRequest($event);

$global = $this->twig->getGlobals();

static::assertSame($admin, $global['admin']);
static::assertSame('ajax.html.twig', $global['base_template']);
}
}

0 comments on commit 8f51141

Please sign in to comment.