fix: properly forward return urls where missing

This commit is contained in:
Björn Fromme
2026-08-11 14:34:46 +02:00
parent 102e1c1c3c
commit 48cd2d6b67
27 changed files with 194 additions and 24 deletions
@@ -39,6 +39,7 @@ class DeleteController extends AbstractController
return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $application->getAssignment()->getUuid(),
'r' => $request->query->get('r'),
]));
}
@@ -46,6 +46,7 @@ class DisposeController extends AbstractController
$redirectUrl = $this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $application->getAssignment()->getUuid(),
'r' => $request->query->get('r'),
]);
return new HxRedirectResponse($redirectUrl);
@@ -57,6 +57,7 @@ class StatusController extends AbstractController
return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $application->getAssignment()->getUuid(),
'r' => $request->query->get('r'),
]));
}
@@ -53,6 +53,7 @@ class DeleteController extends AbstractController
return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $disposition->getAssignment()->getUuid(),
'r' => $request->query->get('r'),
]));
}
@@ -44,6 +44,7 @@ class SkillsController extends AbstractController
return $this->redirectToRoute('app_admin_teamer_skills', [
'uuid' => $teamer->getUuid(),
'r' => $request->query->get('r'),
]);
}
@@ -55,6 +55,7 @@ class DuplicateController extends AbstractController
return $this->redirectToRoute('app_administrative_assignment_edit', [
'uuid' => $copy->getUuid(),
'r' => $request->query->get('r'),
]);
}
@@ -38,6 +38,7 @@ class BusProNetSyncToggleController extends AbstractController
return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $disposition->getAssignment()->getUuid(),
'r' => $request->query->get('r'),
]));
}
}
@@ -55,6 +55,7 @@ class CallOffController extends AbstractController
return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $assignment->getUuid(),
'r' => $request->query->get('r'),
]));
}
@@ -61,6 +61,7 @@ class DocumentUploadController extends AbstractController
return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $disposition->getAssignment()->getUuid(),
'r' => $request->query->get('r'),
]));
}
@@ -38,6 +38,7 @@ class SpecialAgreementsController extends AbstractController
return new HxRedirectResponse($this->generateUrl('app_administrative_assignment_detail', [
'uuid' => $disposition->getAssignment()->getUuid(),
'r' => $request->query->get('r'),
]));
}
@@ -24,7 +24,13 @@ class InfoController extends AbstractController
#[IsGranted(new Expression('is_granted("ROLE_ADMINISTRATIVE") or is_granted("ROLE_HOUSE_MANAGER")'))]
public function index(Teamer $teamer, Request $request): Response
{
$returnUrl = $this->getReturnUrl($request, 'app_administrative_assignment_index');
// House managers reach this modal but not the administrative overviews,
// so their fallback has to stay inside their own area.
$defaultReturnUrlRoute = $this->isGranted('ROLE_ADMINISTRATIVE')
? 'app_administrative_assignment_index'
: 'app_house_manager_index';
$returnUrl = $this->getReturnUrl($request, $defaultReturnUrlRoute);
$recentDispositions = $this->dispositionRepository->findRecentDispositionsByTeamer($teamer);
@@ -66,6 +66,7 @@ class DetailController extends AbstractController
return $this->redirectToRoute('app_teamer_disposition_detail', [
'uuid' => $disposition->getUuid(),
'r' => $request->query->get('r'),
]);
}
+8 -2
View File
@@ -8,9 +8,15 @@ trait ReturnUrlTrait
{
public function getReturnUrl(Request $request, string $defaultRoute, array $parameters = []): string
{
$defaultUrl = $this->generateUrl($defaultRoute, $parameters);
$returnUrl = $request->query->get('r');
return rawurldecode($request->query->get('r', $defaultUrl));
// An empty "r" reaches us whenever a link forwards a return url it never got
// itself, it must not be mistaken for a return url pointing at the root.
if (false === is_string($returnUrl) || '' === $returnUrl) {
return $this->generateUrl($defaultRoute, $parameters);
}
return rawurldecode($returnUrl);
}
/**
+1
View File
@@ -32,6 +32,7 @@ class AppExtension extends AbstractExtension
new TwigFunction('icon', [AppRuntime::class, 'renderIcon'], ['needs_environment' => true, 'is_safe' => ['html']]),
new TwigFunction('is_current_route', [AppRuntime::class, 'isCurrentRoute']),
new TwigFunction('return_url', [AppRuntime::class, 'getEncodedReturnUrl']),
new TwigFunction('forwarded_return_url', [AppRuntime::class, 'getForwardedReturnUrl']),
new TwigFunction('qa_attribute', [AppRuntime::class, 'renderQaAttribute'], ['is_safe' => ['html']]),
new TwigFunction('has_pickup', [AppRuntime::class, 'hasPickup']),
];
+15
View File
@@ -192,6 +192,21 @@ class AppRuntime implements RuntimeExtensionInterface
return rawurlencode($masterRequest->getRequestUri());
}
/**
* Passes the return url of the current page on to the next one.
*
* Used by links that lead deeper into a detail view or trigger an action on it:
* they have to keep pointing back at where the user originally came from instead
* of at the page they sit on. Null when there is nothing to pass on, so that the
* url generator drops the parameter rather than emitting an empty one.
*/
public function getForwardedReturnUrl(): ?string
{
$returnUrl = $this->requestStack->getMainRequest()?->query->get('r');
return is_string($returnUrl) && '' !== $returnUrl ? $returnUrl : null;
}
public function renderQaAttribute(string $label, ?string $value = null): string
{
if ('test' !== $this->environment) {