|
15 | 15 | use Symfony\Component\HttpFoundation\Request;
|
16 | 16 | use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
17 | 17 | use Symfony\Component\HttpKernel\KernelEvents;
|
18 |
| -use Symfony\Component\Routing\RouterInterface; |
19 | 18 | use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadataFactory;
|
| 19 | +use Symfony\UX\LiveComponent\Util\UrlFactory; |
20 | 20 |
|
21 | 21 | class LiveUrlSubscriber implements EventSubscriberInterface
|
22 | 22 | {
|
23 | 23 | private const URL_HEADER = 'X-Live-Url';
|
24 | 24 |
|
25 | 25 | public function __construct(
|
26 |
| - private readonly RouterInterface $router, |
27 |
| - private readonly LiveComponentMetadataFactory $metadataFactory, |
| 26 | + private LiveComponentMetadataFactory $metadataFactory, |
| 27 | + private UrlFactory $urlFactory, |
28 | 28 | ) {
|
29 | 29 | }
|
30 | 30 |
|
31 | 31 | public function onKernelResponse(ResponseEvent $event): void
|
32 | 32 | {
|
33 |
| - if (!$this->isLiveComponentRequest($request = $event->getRequest())) { |
| 33 | + $request = $event->getRequest(); |
| 34 | + if (!$request->attributes->has('_live_component')) { |
34 | 35 | return;
|
35 | 36 | }
|
36 | 37 | if (!$event->isMainRequest()) {
|
37 | 38 | return;
|
38 | 39 | }
|
39 | 40 |
|
| 41 | + $newUrl = null; |
40 | 42 | if ($previousLocation = $request->headers->get(self::URL_HEADER)) {
|
41 |
| - $newUrl = $this->computeNewUrl( |
42 |
| - $previousLocation, |
43 |
| - $this->getLivePropsToMap($request) |
44 |
| - ); |
45 |
| - if ($newUrl) { |
46 |
| - $event->getResponse()->headers->set( |
47 |
| - self::URL_HEADER, |
48 |
| - $newUrl |
| 43 | + $liveProps = $this->getLivePropsToMap($request); |
| 44 | + if (!empty($liveProps)) { |
| 45 | + $newUrl = $this->urlFactory->createFromPreviousAndProps( |
| 46 | + $previousLocation, |
| 47 | + $liveProps['path'], |
| 48 | + $liveProps['query'] |
49 | 49 | );
|
50 | 50 | }
|
51 | 51 | }
|
| 52 | + |
| 53 | + if ($newUrl) { |
| 54 | + $event->getResponse()->headers->set( |
| 55 | + self::URL_HEADER, |
| 56 | + $newUrl |
| 57 | + ); |
| 58 | + } |
52 | 59 | }
|
53 | 60 |
|
54 | 61 | public static function getSubscribedEvents(): array
|
@@ -82,44 +89,4 @@ private function getLivePropsToMap(Request $request): array
|
82 | 89 |
|
83 | 90 | return $urlLiveProps;
|
84 | 91 | }
|
85 |
| - |
86 |
| - private function computeNewUrl(string $previousUrl, array $livePropsToMap): string |
87 |
| - { |
88 |
| - $parsed = parse_url($previousUrl); |
89 |
| - |
90 |
| - $url = $parsed['path'] ?? ''; |
91 |
| - if (isset($parsed['query'])) { |
92 |
| - $url .= '?'.$parsed['query']; |
93 |
| - } |
94 |
| - parse_str($parsed['query'] ?? '', $previousQueryParams); |
95 |
| - |
96 |
| - $newUrl = $this->router->generate( |
97 |
| - $this->router->match($url)['_route'], |
98 |
| - array_merge($previousQueryParams, $livePropsToMap['path']) |
99 |
| - ); |
100 |
| - parse_str(parse_url($newUrl)['query'] ?? '', $queryParams); |
101 |
| - $queryString = http_build_query(array_merge($queryParams, $livePropsToMap['query'])); |
102 |
| - |
103 |
| - return preg_replace('/[?#].*/', '', $newUrl). |
104 |
| - ('' !== $queryString ? '?' : ''). |
105 |
| - $queryString; |
106 |
| - } |
107 |
| - |
108 |
| - /** |
109 |
| - * copied from LiveComponentSubscriber. |
110 |
| - */ |
111 |
| - private function isLiveComponentRequest(Request $request): bool |
112 |
| - { |
113 |
| - if (!$request->attributes->has('_live_component')) { |
114 |
| - return false; |
115 |
| - } |
116 |
| - |
117 |
| - // if ($this->testMode) { |
118 |
| - // return true; |
119 |
| - // } |
120 |
| - |
121 |
| - // Except when testing, require the correct content-type in the Accept header. |
122 |
| - // This also acts as a CSRF protection since this can only be set in accordance with same-origin/CORS policies. |
123 |
| - return \in_array('application/vnd.live-component+html', $request->getAcceptableContentTypes(), true); |
124 |
| - } |
125 | 92 | }
|
0 commit comments