diff --git a/src/Controller/CRUDController.php b/src/Controller/CRUDController.php index 998d937855..b7245b8d91 100644 --- a/src/Controller/CRUDController.php +++ b/src/Controller/CRUDController.php @@ -989,6 +989,25 @@ final public function configureAdmin(Request $request): void $this->templateRegistry = $this->admin->getTemplateRegistry(); } + /** + * Add twig globals which are used in every template. + */ + final public function setTwigGlobals(Request $request): void + { + $twig = $this->container->get('twig'); + \assert($twig instanceof Environment); + + $twig->addGlobal('admin', $this->admin); + + if ($this->isXmlHttpRequest($request)) { + $baseTemplate = $this->templateRegistry->getTemplate('ajax'); + } else { + $baseTemplate = $this->templateRegistry->getTemplate('layout'); + } + + $twig->addGlobal('base_template', $baseTemplate); + } + /** * Renders a view while passing mandatory parameters on to the template. * diff --git a/src/EventListener/AdminEventListener.php b/src/EventListener/AdminEventListener.php deleted file mode 100644 index 64bbb57bd6..0000000000 --- a/src/EventListener/AdminEventListener.php +++ /dev/null @@ -1,83 +0,0 @@ - - * - * 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 - */ -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) { - } - } -} diff --git a/src/EventListener/ConfigureCRUDControllerListener.php b/src/EventListener/ConfigureCRUDControllerListener.php index d7fb30b286..cc3179abfc 100644 --- a/src/EventListener/ConfigureCRUDControllerListener.php +++ b/src/EventListener/ConfigureCRUDControllerListener.php @@ -38,6 +38,8 @@ public function onKernelController(ControllerEvent $event): void $request = $event->getRequest(); $controller->configureAdmin($request); + + $controller->setTwigGlobals($request); } public static function getSubscribedEvents(): array diff --git a/src/Resources/config/event_listener.php b/src/Resources/config/event_listener.php index c585909e9c..105ddc77bb 100644 --- a/src/Resources/config/event_listener.php +++ b/src/Resources/config/event_listener.php @@ -13,19 +13,11 @@ 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'); }; diff --git a/tests/Controller/CRUDControllerTest.php b/tests/Controller/CRUDControllerTest.php index 4f23eabb4e..e102513c8f 100644 --- a/tests/Controller/CRUDControllerTest.php +++ b/tests/Controller/CRUDControllerTest.php @@ -74,6 +74,7 @@ use Symfony\Component\Validator\ConstraintViolation; use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Environment; +use Twig\Loader\ArrayLoader; /** * @author Andrej Hudec @@ -383,6 +384,32 @@ public function testConfigureAdminWithoutTemplateRegistryThrowsException(): void $controller->configureAdmin($this->request); } + public function testSetTwigGlobals(): void + { + $twig = new Environment(new ArrayLoader([])); + $this->container->set('twig', $twig); + + $this->controller->setTwigGlobals($this->request); + + $globals = $twig->getGlobals(); + static::assertSame($this->admin, $globals['admin']); + static::assertSame('@SonataAdmin/standard_layout.html.twig', $globals['base_template']); + } + + public function testSetTwigGlobalsWithAjaxRequest(): void + { + $this->request->request->set('_xml_http_request', true); + + $twig = new Environment(new ArrayLoader([])); + $this->container->set('twig', $twig); + + $this->controller->setTwigGlobals($this->request); + + $globals = $twig->getGlobals(); + static::assertSame($this->admin, $globals['admin']); + static::assertSame('@SonataAdmin/ajax_layout.html.twig', $globals['base_template']); + } + public function testGetBaseTemplate(): void { static::assertSame( diff --git a/tests/EventListener/AdminEventListenerTest.php b/tests/EventListener/AdminEventListenerTest.php deleted file mode 100644 index 2608deaa59..0000000000 --- a/tests/EventListener/AdminEventListenerTest.php +++ /dev/null @@ -1,107 +0,0 @@ - - * - * 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']); - } -} diff --git a/tests/EventListener/ConfigureCRUDControllerListenerTest.php b/tests/EventListener/ConfigureCRUDControllerListenerTest.php index 87c7e8f79f..ee9e45c9a3 100644 --- a/tests/EventListener/ConfigureCRUDControllerListenerTest.php +++ b/tests/EventListener/ConfigureCRUDControllerListenerTest.php @@ -22,6 +22,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\ControllerEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; +use Twig\Environment; final class ConfigureCRUDControllerListenerTest extends TestCase { @@ -64,6 +65,21 @@ public function testItConfiguresCRUDController(): void ->with($request) ->willReturn($admin); + $twig = $this->createMock(Environment::class); + $container->set('twig', $twig); + + $matcher = static::exactly(2); + $twig + ->expects($matcher) + ->method('addGlobal') + ->willReturnCallback(function (string $name) use ($matcher) { + match ($matcher->getInvocationCount()) { + 1 => static::assertEquals($name, 'admin'), + 2 => static::assertEquals($name, 'base_template'), + default => throw new \LogicException('Exactly 2 calls'), + }; + }); + $this->listener->onKernelController($controllerEvent); } }