Skip to content

Commit 79556db

Browse files
authored
fix query parameter merging for urls without path part (respecting fragment part) (#203)
1 parent d8e6f31 commit 79556db

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

src/Http/Middleware/HandleNotFound.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,16 @@ public function mergeQuery(Request $request, string $destination): string
160160
ksort($query);
161161

162162
if (count($query)) {
163-
$destination = $destination_parsed['path'] . '?' . http_build_query($query);
163+
// make sure to preserve fragment if specified in destination
164+
$fragment = isset($destination_parsed['fragment']) ? '#' . $destination_parsed['fragment'] : '';
165+
if (($urlBeforeFragment = strstr($destination, '#', true)) === false) {
166+
$urlBeforeFragment = $destination;
167+
}
168+
if (($urlBeforeQuery = strstr($urlBeforeFragment, '?', true)) === false) {
169+
$urlBeforeQuery = $destination;
170+
}
171+
172+
$destination = $urlBeforeQuery . '?' . http_build_query($query) . $fragment;
164173
}
165174

166175
return $destination;

tests/Feature/Middleware/HandleNotFoundTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,62 @@ public function it_merges_query_strings()
260260
$this->assertTrue($response->isRedirect(url('/fr?another=value&lang=fr')));
261261
}
262262

263+
/**
264+
* @test
265+
*/
266+
public function it_merges_query_strings_on_urls_without_path()
267+
{
268+
config()->set('statamic.redirect.preserve_query_strings', true);
269+
270+
Redirect::make()
271+
->source('/abc?another=value')
272+
->destination('?lang=fr')
273+
->save();
274+
275+
$response = $this->middleware->handle(Request::create('/abc', 'GET', ['another' => 'value']), function () {
276+
return (new Response('', 404));
277+
});
278+
279+
$this->assertTrue($response->isRedirect(url('?another=value&lang=fr')));
280+
}
281+
282+
/**
283+
* @test
284+
*/
285+
public function it_merges_query_strings_on_urls_with_fragment()
286+
{
287+
config()->set('statamic.redirect.preserve_query_strings', true);
288+
289+
Redirect::make()
290+
->source('/abc?another=value')
291+
->destination('/abc?lang=fr#some-fragment?with=fragment_param')
292+
->save();
293+
294+
$response = $this->middleware->handle(Request::create('/abc', 'GET', ['another' => 'value']), function () {
295+
return (new Response('', 404));
296+
});
297+
298+
$this->assertTrue($response->isRedirect(url('/abc?another=value&lang=fr#some-fragment?with=fragment_param')));
299+
}
300+
301+
/**
302+
* @test
303+
*/
304+
public function it_merges_query_strings_on_urls_without_path_with_fragment()
305+
{
306+
config()->set('statamic.redirect.preserve_query_strings', true);
307+
308+
Redirect::make()
309+
->source('/abc?another=value')
310+
->destination('?lang=fr#some-fragment?with=fragment_param')
311+
->save();
312+
313+
$response = $this->middleware->handle(Request::create('/abc', 'GET', ['another' => 'value']), function () {
314+
return (new Response('', 404));
315+
});
316+
317+
$this->assertTrue($response->isRedirect(url('?another=value&lang=fr#some-fragment?with=fragment_param')));
318+
}
263319

264320

265321
/**

0 commit comments

Comments
 (0)