Skip to content

Commit

Permalink
Framework\Uri: Improve query parameter handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mahagr committed Feb 17, 2018
1 parent 0a79788 commit 17ba58a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
5 changes: 2 additions & 3 deletions system/src/Grav/Framework/Uri/Uri.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ public function withQueryParam($key, $value)
public function getQueryParams()
{
if ($this->queryParams === null) {
parse_str($this->getQuery(), $this->queryParams);
array_map(function($str) { return rawurldecode($str); }, $this->queryParams);
$this->queryParams = UriFactory::parseQuery($this->getQuery(), true);
}

return $this->queryParams;
Expand All @@ -122,7 +121,7 @@ public function getQueryParams()
*/
public function withQueryParams(array $params)
{
$query = $params ? http_build_query($params) : '';
$query = UriFactory::buildQuery($params);

return $this->withQuery($query);
}
Expand Down
52 changes: 43 additions & 9 deletions system/src/Grav/Framework/Uri/UriFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public static function parseUrlFromEnvironment(array $env)

// Build path.
$request_uri = isset($env['REQUEST_URI']) ? $env['REQUEST_URI'] : '';
$path = rawurldecode(parse_url('http://example.com' . $request_uri, PHP_URL_PATH));
$path = parse_url('http://example.com' . $request_uri, PHP_URL_PATH);

// Build query string.
$query = isset($env['QUERY_STRING']) ? $env['QUERY_STRING'] : '';
Expand All @@ -107,24 +107,58 @@ public static function parseUrlFromEnvironment(array $env)
}

/**
* Advanced `parse_url()` method.
* UTF-8 aware parse_url() implementation.
*
* @param string $uri
* @param string $url
* @return array
* @throws \InvalidArgumentException
*/
public static function parseUrl($uri)
public static function parseUrl($url)
{
if (!is_string($uri)) {
throw new \InvalidArgumentException('Uri must be a string');
if (!is_string($url)) {
throw new \InvalidArgumentException('URL must be a string');
}

// Set Uri parts.
$parts = parse_url($uri);
$encodedUrl = preg_replace_callback(
'%[^:/@?&=#]+%u',
function ($matches) { return rawurlencode($matches[0]); },
$url
);

$parts = parse_url($encodedUrl);
if ($parts === false) {
throw new \InvalidArgumentException('Malformed URI: ' . $uri);
throw new \InvalidArgumentException('Malformed URL: ' . $encodedUrl);
}

return $parts;
}

/**
* Parse query string and return it as an array.
*
* @param string $query
* @params bool $decode
* @return mixed
*/
public static function parseQuery($query, $decode = false)
{
parse_str($query, $params);

if ($decode) {
array_map(function($str) { return rawurldecode($str); }, $params);
}

return $params;
}

/**
* Build query string from variables.
*
* @param array $params
* @return string
*/
public static function buildQuery(array $params)
{
return $params ? http_build_query($params, null, ini_get('arg_separator.output'), PHP_QUERY_RFC3986) : '';
}
}

0 comments on commit 17ba58a

Please sign in to comment.