From f452fa8039361590ea31ac1c206d777fdcf147af Mon Sep 17 00:00:00 2001
From: Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de>
Date: Wed, 18 May 2022 06:40:51 +0000
Subject: [PATCH] fix behaviour of `url_for` with fragments, fixes #985

Closes #985

Merge request studip/studip!630
---
 app/controllers/studip_controller.php           | 17 +++++++----------
 tests/unit/lib/classes/StudipControllerTest.php |  4 ++++
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/app/controllers/studip_controller.php b/app/controllers/studip_controller.php
index 5cdb3de3960..cad182ae55a 100644
--- a/app/controllers/studip_controller.php
+++ b/app/controllers/studip_controller.php
@@ -275,6 +275,11 @@ abstract class StudipController extends Trails_Controller
             throw new InvalidArgumentException(__METHOD__ . ' cannot be used with absolute URLs');
         }
 
+        // Extract fragment (if any)
+        if (strpos($to, '#') !== false) {
+            list($args[0], $fragment) = explode('#', $to);
+        }
+
         // Extract parameters (if any)
         $params = [];
         if (is_array(end($args))) {
@@ -289,17 +294,9 @@ abstract class StudipController extends Trails_Controller
             return $arg;
         }, $args);
 
-        // Combine arguments to new $to string
-        $to = implode('/', $args);
-
-        //preserve fragment
-        $to_parts = explode('#', $to);
-        $to = $to_parts[0];
-        $fragment = $to_parts[1] ?? '';
-
-        $url = parent::url_for($to);
+        $url = parent::url_for(...$args);
 
-        if ($fragment) {
+        if (isset($fragment)) {
             $url .= '#' . $fragment;
         }
         return URLHelper::getURL($url, $params);
diff --git a/tests/unit/lib/classes/StudipControllerTest.php b/tests/unit/lib/classes/StudipControllerTest.php
index fae7628d269..3675f58f14b 100644
--- a/tests/unit/lib/classes/StudipControllerTest.php
+++ b/tests/unit/lib/classes/StudipControllerTest.php
@@ -185,6 +185,10 @@ final class StudipControllerTest extends Codeception\Test\Unit
             '2-actions'                => ['dispatch.php/foo/bar', 'foo', 'bar'],
             '2-actions-and-parameter'  => ['dispatch.php/foo/bar?bar=42', 'foo', 'bar', ['bar' => 42]],
             '2-actions-and-parameters' => ['dispatch.php/foo/bar?bar=42&baz=23', 'foo', 'bar', ['bar' => 42, 'baz' => 23]],
+
+            'fragment'                 => ['dispatch.php/foo/bar/42/23#jump', 'foo/bar/42/23#jump'],
+            'fragment-and-parameters'  => ['dispatch.php/foo/bar/42/23#jump', 'foo/bar#jump', 42, 23],
+            'url-encoding-parameters'  => ['dispatch.php/foo/bar/%3Fabc/%2F', 'foo/bar', '?abc', '/'],
         ];
     }
 
-- 
GitLab