Fixed Cannot read get parameter after link method

AlessioDP

Member
Affected version
2.0.2
I have some problems to get parameters if there are an hash into the link:
Code:
http://xxxxx.net/index.php?var=1
http://xxxxx.net/index.php#category.1?var=1

I cannot get 'var' with the second case.

I use this code to generate the link:
Code:
{{ link('categories', $node, {'var': 1}))


Posting here due to:
I would consider reporting this as a bug, I would expect the parameters to be appended to the route (before the hash). It looks like it might have something to do with the assertCanonicalUrl() call in the category controller.
 
The problem is that everything after the hash # is part of the URL fragment (https://en.wikipedia.org/wiki/Fragment_identifier) which the browser doesn't even send to the server. There is no way to access the var parameter in http://xxxxx.net/index.php#category.1?var=1 from PHP. The fragment can only be accessed by JavaScript.

The issue seems to be that XenForo's "link" function builds a broken link in this specific case. I think it should return http://xxxxx.net/index.php?var=1#category.1.
 
The problem is that everything after the hash # is part of the URL fragment (https://en.wikipedia.org/wiki/Fragment_identifier) which the browser doesn't even send to the server. There is no way to access the var parameter in http://xxxxx.net/index.php#category.1?var=1 from PHP. The fragment can only be accessed by JavaScript.

The issue seems to be that XenForo's "link" function builds a broken link in this specific case. I think it should return http://xxxxx.net/index.php?var=1#category.1.
Exactly, for that I've posted it in Bug reports.
 
I have some problems to get parameters if there are an hash into the link:
Code:
http://xxxxx.net/index.php?var=1
http://xxxxx.net/index.php#category.1?var=1

I cannot get 'var' with the second case.

I use this code to generate the link:
Code:
{{ link('categories', $node, {'var': 1}))


Posting here due to:
Are you sure you're not including the hash in the route configuration? If you are, then that's the problem.


Fillip
 
Are you sure you're not including the hash in the route configuration? If you are, then that's the problem.


Fillip
I'm sure, I've a default XenForo installed, and I work on it.

I can write a simple example here:
Basically you have a link like that in your homepage: http://xxxx.yyy/index.php?posts/9/
I can rewrite it with link function inside XenForo template and it becomes: http://xxxx.yyy/index.php?posts/9/&var=1

When you press enter it becomes: http://xxxx.yy/index.php?threads/my-thread.1/#post-9&var=1
As you can see, it automatically edit the link to let it point to the post and it insert wrongly parameters.
 
Pretty sure this is fixed now with some special handling for hash fragments:
Diff:
Index: src/XF/Mvc/Controller.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/XF/Mvc/Controller.php    (date 1523983085000)
+++ src/XF/Mvc/Controller.php    (date 1524052983000)
@@ -508,7 +508,17 @@
             $redirectUrl = rtrim($fullBasePath, '/') . '/' . $linkUrlPrefix;
             if ($requestParams !== false)
             {
-                $redirectUrl .= (strpos($redirectUrl, '?') === false ? '?' : '&') . $requestParams;
+                $paramsSep = (strpos($redirectUrl, '?') === false ? '?' : '&');
+
+                if (strpos($redirectUrl, '#') !== false)
+                {
+                    list ($link, $hash) = explode('#', $redirectUrl, 2);
+                    $redirectUrl = $link . $paramsSep . $requestParams . '#' . $hash;
+                }
+                else
+                {
+                    $redirectUrl .= $paramsSep . $requestParams;
+                }
             }
 
             throw $this->exception($this->redirectPermanently($redirectUrl));
 
Pretty sure this is fixed now with some special handling for hash fragments:
Diff:
Index: src/XF/Mvc/Controller.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/XF/Mvc/Controller.php    (date 1523983085000)
+++ src/XF/Mvc/Controller.php    (date 1524052983000)
@@ -508,7 +508,17 @@
             $redirectUrl = rtrim($fullBasePath, '/') . '/' . $linkUrlPrefix;
             if ($requestParams !== false)
             {
-                $redirectUrl .= (strpos($redirectUrl, '?') === false ? '?' : '&') . $requestParams;
+                $paramsSep = (strpos($redirectUrl, '?') === false ? '?' : '&');
+
+                if (strpos($redirectUrl, '#') !== false)
+                {
+                    list ($link, $hash) = explode('#', $redirectUrl, 2);
+                    $redirectUrl = $link . $paramsSep . $requestParams . '#' . $hash;
+                }
+                else
+                {
+                    $redirectUrl .= $paramsSep . $requestParams;
+                }
             }

             throw $this->exception($this->redirectPermanently($redirectUrl));
Not completely fixed, I've edited the source controller and this is the result:
Test 1, category link:
Code:
Code: {{ link('categories', $node, {'var': 1}) }}
Result: http://xxxxx.yyy/index.php?categories/main-category.1/&var=1
Result after link load: http://xxxxx.yy/index.php?var=1#main-category.1

Test 2, last post link:
Code:
Code: {{ link('posts', {'post_id': $extras.last_post_id}, {'var': 1}) }}
Result: http://xxxxx.yyy/index.php?posts/9/&var=1
Result after link load: http://xxxxx.yy/index.php?threads/discussion-name.2/#post-9

So in the first case it works, but in the second one it doesn't. I suppose that somewhere else a link to re-write ?posts/ is still using the old way and it remove the GET parameter.
 
That's really a totally different case and there isn't really an expectation that it would work. The main issue in this thread is actually generating an invalid link, hence it's worth fixing.

What you want in the second case is to totally change the URL that the posts link redirects to, so that's something you'd need to take care of yourself by extending the Post::actionIndex controller action or the Thread::getPostLink controller plugin method.
 
Top Bottom