Skip to content

Commit 9d1560c

Browse files
committed
bug #2976 [LiveComponent] Fix #[LiveProp(writable: true, url: true)] that was not updated as a query parameter (mbuliard)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [LiveComponent] Fix `#[LiveProp(writable: true, url: true)]` that was not updated as a query parameter | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Docs? | no | Issues | Fix #2960 Fix #2975 | License | MIT Hi, The LiveUrl feature in 2.28 introduced a few bugs and I would like to fix some : * The symfony matcher uses the current method to find the route. The UrlFactory must temporarily replace it by a GET. Will fix the MethodNotAllowedException bug of #2960 #2975 * The symfony matcher should not be given the query, only the path. Commits ------- 39a2843 [LiveComponent] Fix `#[LiveProp(writable: true, url: true)]` that was not updated as a query parameter
2 parents 352953d + 39a2843 commit 9d1560c

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

src/LiveComponent/src/Util/UrlFactory.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,8 @@ public function createFromPreviousAndProps(
3636
return null;
3737
}
3838

39-
// Make sure to handle only path and query
40-
$previousUrl = $parsed['path'] ?? '';
41-
if (isset($parsed['query'])) {
42-
$previousUrl .= '?'.$parsed['query'];
43-
}
44-
4539
try {
46-
$newUrl = $this->createPath($previousUrl, $pathMappedProps);
40+
$newUrl = $this->createPath($parsed['path'] ?? '', $pathMappedProps);
4741
} catch (ResourceNotFoundException|MethodNotAllowedException|MissingMandatoryParametersException) {
4842
return null;
4943
}
@@ -60,10 +54,27 @@ public function createFromPreviousAndProps(
6054

6155
private function createPath(string $previousUrl, array $props): string
6256
{
63-
return $this->router->generate(
64-
$this->router->match($previousUrl)['_route'] ?? '',
57+
$newPath = $this->router->generate(
58+
$this->matchRoute($previousUrl),
6559
$props
6660
);
61+
62+
return $newPath;
63+
}
64+
65+
private function matchRoute(string $previousUrl): string
66+
{
67+
$context = $this->router->getContext();
68+
$tmpContext = clone $context;
69+
$tmpContext->setMethod('GET');
70+
$this->router->setContext($tmpContext);
71+
try {
72+
$match = $this->router->match($previousUrl);
73+
} finally {
74+
$this->router->setContext($context);
75+
}
76+
77+
return $match['_route'] ?? '';
6778
}
6879

6980
private function replaceQueryString($url, array $props): string

src/LiveComponent/tests/Fixtures/Kernel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ protected function configureRoutes(RoutingConfigurator $routes): void
217217
$routes->add('homepage', '/')->controller('kernel::index');
218218
$routes->add('alternate_live_route', '/alt/{_live_component}/{_live_action}')->defaults(['_live_action' => 'get']);
219219
$routes->add('localized_route', '/locale/{_locale}/{_live_component}/{_live_action}')->defaults(['_live_action' => 'get']);
220-
$routes->add('route_with_prop', '/route_with_prop/{pathProp}');
220+
$routes->add('route_with_prop', '/route_with_prop/{pathProp}')->methods(['GET']);
221221
$routes->add('route_with_alias_prop', '/route_with_alias_prop/{pathAlias}');
222222
}
223223
}

src/LiveComponent/tests/Unit/Util/UrlFactoryTest.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
1616
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
1717
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
18+
use Symfony\Component\Routing\RequestContext;
1819
use Symfony\Component\Routing\RouterInterface;
1920
use Symfony\UX\LiveComponent\Util\UrlFactory;
2021

@@ -40,10 +41,10 @@ public static function provideTestCreate(): \Generator
4041

4142
yield 'keep_url_with_query_parameters' => [
4243
'input' => ['previousUrl' => 'https://symfony.com/foo/bar?prop1=val1&prop2=val2'],
43-
'/foo/bar?prop1=val1&prop2=val2',
44+
'expectedUrl' => '/foo/bar?prop1=val1&prop2=val2',
4445
'routerStubData' => [
45-
'previousUrl' => '/foo/bar?prop1=val1&prop2=val2',
46-
'newUrl' => '/foo/bar?prop1=val1&prop2=val2',
46+
'previousUrl' => '/foo/bar',
47+
'newUrl' => '/foo/bar',
4748
],
4849
];
4950

@@ -61,6 +62,10 @@ public static function provideTestCreate(): \Generator
6162
'queryMappedProps' => ['prop1' => 'val1', 'prop2' => 'val2'],
6263
],
6364
'expectedUrl' => '/foo/bar?prop1=val1&prop3=oldValue&prop2=val2',
65+
'routerStubData' => [
66+
'previousUrl' => '/foo/bar',
67+
'newUrl' => '/foo/bar',
68+
],
6469
];
6570

6671
yield 'add_path_parameters' => [
@@ -178,7 +183,13 @@ private function createRouterStub(
178183
array $props = [],
179184
): RouterInterface {
180185
$matchedRoute = 'default';
186+
$context = $this->createMock(RequestContext::class);
181187
$router = $this->createMock(RouterInterface::class);
188+
$router->expects(self::once())
189+
->method('getContext')
190+
->willReturn($context);
191+
$router->expects(self::exactly(2))
192+
->method('setContext');
182193
$router->expects(self::once())
183194
->method('match')
184195
->with($previousUrl)

0 commit comments

Comments
 (0)