summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--it_html.class14
-rwxr-xr-xtests/it_html.t13
2 files changed, 21 insertions, 6 deletions
diff --git a/it_html.class b/it_html.class
index 1ca2acf..ea8a159 100644
--- a/it_html.class
+++ b/it_html.class
@@ -542,6 +542,7 @@ static function U(/* ... */)
if (!($u = @parse_url($base)))
list($u['path'], $u['query']) = explode("?", $base, 2);
+ parse_str($u['query'], $u['params']);
$u['host'] = preg_match('/[^-_.0-9a-z]/i', $u['host']) && function_exists('idn_to_ascii') && ($idnahost = idn_to_ascii($GLOBALS['it_html']->p['charset'] == "iso-8859-1" ? utf8_encode($u['host']) : $u['host'])) ? $idnahost : $u['host']; # Punycode hostname to include into webpage
$u['host'] = preg_replace_callback('/[^-_.0-9a-z\x80-\xff]/i', function($m) { return rawurlencode($m[0]); }, $u['host']); # Encode garbage chars in host
@@ -554,20 +555,23 @@ static function U(/* ... */)
$schemepart = $hostpart ? ($u['scheme'] ? $u['scheme'] . ":" : "") . "//$hostpart" : ($u['scheme'] == "mailto" ? $u['scheme'] . ":" : "");
- $path = $u['path'] . ($u['query'] ? "?" . strtr($u['query'], array("?" => rawurlencode("?"))) : "") . ($u['fragment'] ? "#" . $u['fragment'] : "");
-
# hack: encode % if not followed by two hex digits
- $parts = preg_split('/%([^%]{0,2})/', $path, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $parts = preg_split('/%([^%]{0,2})/', $u['path'], -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 1; $i < count($parts); $i+=2)
$parts[$i] = (preg_match('/[0-9a-f][0-9a-f]/i', $parts[$i]) ? "%" : "%25") . $parts[$i];
$path = join("", $parts);
+ # if params replace url parameters that are present in base, replace them but keep their order
+ foreach ($u['params'] as $key => $dummy)
+ if (isset($params[$key]))
+ $u['params'][$key] = $params[$key];
+
$path = preg_replace_callback('|[^-a-z0-9_.+!*(),:?@&=/~$%#]|i', function($m) { return rawurlencode($m[0]); }, $path);
$path = preg_replace('|^([a-z0-9_]+:)?//[^/]*$|', '$0/', $path); # Add slash if absolute url without a path, e.g. http://gna.ch
- $queryparams = it_url::params($params);
+ $queryparams = it_url::params($u['params'] + $params);
$separator = strpos($path, "?") === false ? "?" : "&";
- return $schemepart . $path . ($queryparams ? "$separator$queryparams" : "");
+ return $schemepart . $path . ($queryparams ? "$separator$queryparams" : "") . ($u['fragment'] ? "#" . $u['fragment'] : "");;
}
diff --git a/tests/it_html.t b/tests/it_html.t
index 2dc7be5..538a350 100755
--- a/tests/it_html.t
+++ b/tests/it_html.t
@@ -190,6 +190,17 @@ is(
);
is(
+ U("/foo.html?bar=qux", array('bar' => "baz")),
+ '/foo.html?bar=baz',
+ 'U() args override get params in base url'
+);
+
+is(
+ U("/foo.html?bar=qux#frag=frog", array('baz' => "gna")),
+ '/foo.html?bar=qux&baz=gna#frag=frog',
+ 'U() fragment after params'
+);
+is(
U("Jet d'eau"),
'Jet%20d%27eau',
'U() with single quotes in URL'
@@ -197,7 +208,7 @@ is(
is(
U('/test.html?foo=bar?qux=gna', array('?q' => '?r')),
- '/test.html?foo=bar%3Fqux=gna&%3Fq=%3Fr',
+ '/test.html?foo=bar%3Fqux%3Dgna&%3Fq=%3Fr',
'U() quoting of ? in args but not base'
);
is(