Skip to content

Commit ae70cf2

Browse files
committed
[Turbo] Add stream format with request listener
BundleInterface::boot() is only called when booting a worker and not on every request. Fixes #2549
1 parent 9b322da commit ae70cf2

File tree

5 files changed

+92
-6
lines changed

5 files changed

+92
-6
lines changed

src/Turbo/config/services.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

14+
use Symfony\Component\HttpKernel\KernelEvents;
1415
use Symfony\UX\Turbo\Broadcaster\BroadcasterInterface;
1516
use Symfony\UX\Turbo\Broadcaster\IdAccessor;
1617
use Symfony\UX\Turbo\Broadcaster\ImuxBroadcaster;
1718
use Symfony\UX\Turbo\Broadcaster\TwigBroadcaster;
1819
use Symfony\UX\Turbo\Doctrine\BroadcastListener;
20+
use Symfony\UX\Turbo\Request\RequestListener;
1921
use Symfony\UX\Turbo\Twig\TwigExtension;
2022

2123
/*
@@ -55,5 +57,8 @@
5557
])
5658
->tag('doctrine.event_listener', ['event' => 'onFlush'])
5759
->tag('doctrine.event_listener', ['event' => 'postFlush'])
60+
61+
->set('turbo.kernel.request_listener', RequestListener::class)
62+
->tag('kernel.event_listener', ['event' => KernelEvents::REQUEST, 'priority' => 256])
5863
;
5964
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\Turbo\Request;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\UX\Turbo\TurboBundle;
16+
17+
/**
18+
* Registers the Turbo request format for all requests.
19+
*
20+
* @author Alexander Hofbauer <a.hofbauer@fify.at>
21+
*/
22+
final class RequestListener
23+
{
24+
public function __invoke(): void
25+
{
26+
(new Request())->setFormat(TurboBundle::STREAM_FORMAT, TurboBundle::STREAM_MEDIA_TYPE);
27+
}
28+
}

src/Turbo/src/TurboBundle.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1515
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
17-
use Symfony\Component\HttpFoundation\Request;
1817
use Symfony\Component\HttpKernel\Bundle\Bundle;
1918

2019
/**
@@ -25,11 +24,6 @@ final class TurboBundle extends Bundle
2524
public const STREAM_FORMAT = 'turbo_stream';
2625
public const STREAM_MEDIA_TYPE = 'text/vnd.turbo-stream.html';
2726

28-
public function boot(): void
29-
{
30-
(new Request())->setFormat(self::STREAM_FORMAT, self::STREAM_MEDIA_TYPE);
31-
}
32-
3327
public function build(ContainerBuilder $container): void
3428
{
3529
parent::build($container);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\Turbo\Tests\Request;
13+
14+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
15+
use Symfony\UX\Turbo\TurboBundle;
16+
17+
/**
18+
* Tests the Turbo request listener.
19+
*
20+
* @author Alexander Hofbauer <a.hofbauer@fify.at>
21+
*/
22+
class RequestListenerTest extends WebTestCase
23+
{
24+
public function testAddsTurboRequestFormat(): void
25+
{
26+
$client = static::createClient(server: [
27+
'HTTP_ACCEPT' => 'text/vnd.turbo-stream.html, text/html, application/xhtml+xml',
28+
]);
29+
30+
// simulate worker mode
31+
$client->disableReboot();
32+
33+
// request twice to test if listener is always called
34+
$this->assertPreferredFormat();
35+
$this->assertPreferredFormat();
36+
}
37+
38+
private function assertPreferredFormat(): void
39+
{
40+
$client = static::getClient();
41+
42+
$client->request('POST', '/turboRequest');
43+
44+
$response = $client->getResponse()->getContent();
45+
46+
$this->assertJsonStringEqualsJsonString($response, json_encode([
47+
'preferred_format' => TurboBundle::STREAM_FORMAT,
48+
]));
49+
}
50+
}

src/Turbo/tests/app/Kernel.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
3030
use Symfony\Component\Form\Extension\Core\Type\TextType;
3131
use Symfony\Component\Form\FormFactoryInterface;
32+
use Symfony\Component\HttpFoundation\JsonResponse;
3233
use Symfony\Component\HttpFoundation\Request;
3334
use Symfony\Component\HttpFoundation\Response;
3435
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -144,6 +145,7 @@ protected function configureRoutes(RoutingConfigurator $routes): void
144145
$routes->add('artists', '/artists')->controller('kernel::artists');
145146
$routes->add('artist', '/artists/{id}')->controller('kernel::artist');
146147
$routes->add('artist_from_song', '/artistFromSong')->controller('kernel::artistFromSong');
148+
$routes->add('turbo_request', '/turboRequest')->controller('kernel::turboRequest');
147149
}
148150

149151
public function getProjectDir(): string
@@ -312,4 +314,11 @@ public function artistFromSong(Request $request, EntityManagerInterface $doctrin
312314
'song' => $song,
313315
]));
314316
}
317+
318+
public function turboRequest(Request $request): Response
319+
{
320+
return new JsonResponse([
321+
'preferred_format' => $request->getPreferredFormat(),
322+
]);
323+
}
315324
}

0 commit comments

Comments
 (0)