From 7fc2f20f1b8ff7a45a2cce35f29ff2ddfdb5e5f0 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 30 May 2016 16:41:07 -0600 Subject: [PATCH] Better handling of params with more complex Urls - #859 --- CHANGELOG.md | 1 + system/src/Grav/Common/Uri.php | 42 ++++++++++++------------------ tests/unit/Grav/Common/UriTest.php | 16 ++++++++++++ 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b59a54a8a..8700ef976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Fix for saving fields in expert mode that have no `Validation::typeX()` methods [#626](https://github.com/getgrav/grav-plugin-admin/issues/626) * Detect if user really meant to extend parent blueprint, not another one (fixes old page type blueprints) * Fixed a bug in `Page::relativePagePath()` when `Page::$name` is not defined + * Fix for poor handling of params + query element in `Uri::processParams()` [#859](https://github.com/getgrav/grav/issues/859) # v1.1.0-beta.5 ## 05/23/2016 diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index 3d16b9490..01568cda6 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -12,6 +12,7 @@ use Grav\Common\Page\Page; class Uri { const HOSTNAME_REGEX = '/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/'; + const PARAMS_REGEX = '/\/([^\:\#\/\?]*:[^\:\#\/\?]*)/'; public $url; @@ -349,22 +350,17 @@ class Uri private function processParams($uri, $delimiter = ':') { if (strpos($uri, $delimiter) !== false) { - $bits = explode('/', $uri); - $path = []; - foreach ($bits as $bit) { - if (strpos($bit, $delimiter) !== false) { - $param = explode($delimiter, $bit); - if (count($param) == 2) { - $plain_var = filter_var(rawurldecode($param[1]), FILTER_SANITIZE_STRING); - $this->params[$param[0]] = $plain_var; - } - } else { - $path[] = $bit; + preg_match_all(Uri::PARAMS_REGEX, $uri, $matches, PREG_SET_ORDER); + + foreach ($matches as $match) { + $param = explode($delimiter, $match[1]); + if (count($param) == 2) { + $plain_var = filter_var(rawurldecode($param[1]), FILTER_SANITIZE_STRING); + $this->params[$param[0]] = $plain_var; + $uri = str_replace($match[0], '', $uri); } } - $uri = '/' . ltrim(implode('/', $path), '/'); } - return $uri; } @@ -941,20 +937,16 @@ class Uri $params = []; if (strpos($uri, $delimiter) !== false) { - $bits = explode('/', $uri); - $path = []; - foreach ($bits as $bit) { - if (strpos($bit, $delimiter) !== false) { - $param = explode($delimiter, $bit); - if (count($param) == 2) { - $plain_var = filter_var(rawurldecode($param[1]), FILTER_SANITIZE_STRING); - $params[$param[0]] = $plain_var; - } - } else { - $path[] = $bit; + preg_match_all(Uri::PARAMS_REGEX, $uri, $matches, PREG_SET_ORDER); + + foreach ($matches as $match) { + $param = explode($delimiter, $match[1]); + if (count($param) == 2) { + $plain_var = filter_var(rawurldecode($param[1]), FILTER_SANITIZE_STRING); + $params[$param[0]] = $plain_var; + $uri = str_replace($match[0], '', $uri); } } - $uri = '/' . ltrim(implode('/', $path), '/'); } return [$uri, $params]; diff --git a/tests/unit/Grav/Common/UriTest.php b/tests/unit/Grav/Common/UriTest.php index d2299ac06..c134c3602 100644 --- a/tests/unit/Grav/Common/UriTest.php +++ b/tests/unit/Grav/Common/UriTest.php @@ -148,6 +148,18 @@ class UriTest extends \Codeception\TestCase\Test $this->assertSame('/ueper:xxx/test:yyy', $this->uri->params()); $this->assertSame('/ueper:xxx', $this->uri->params('ueper')); $this->assertSame('/test:yyy', $this->uri->params('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yyy')->init(); + $this->assertSame('/ueper:xxx++/test:yyy', $this->uri->params()); + $this->assertSame('/ueper:xxx++', $this->uri->params('ueper')); + $this->assertSame('/test:yyy', $this->uri->params('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yyy#something')->init(); + $this->assertSame('/ueper:xxx++/test:yyy', $this->uri->params()); + $this->assertSame('/ueper:xxx++', $this->uri->params('ueper')); + $this->assertSame('/test:yyy', $this->uri->params('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yyy?foo=bar')->init(); + $this->assertSame('/ueper:xxx++/test:yyy', $this->uri->params()); + $this->assertSame('/ueper:xxx++', $this->uri->params('ueper')); + $this->assertSame('/test:yyy', $this->uri->params('test')); $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init(); $this->assertSame(null, $this->uri->params()); $this->assertSame(null, $this->uri->params('ueper')); @@ -175,6 +187,10 @@ class UriTest extends \Codeception\TestCase\Test $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init(); $this->assertSame('xxx', $this->uri->param('ueper')); $this->assertSame('yyy', $this->uri->param('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yy%20y/foo:bar_baz-bank')->init(); + $this->assertSame('xxx++', $this->uri->param('ueper')); + $this->assertSame('yy y', $this->uri->param('test')); + $this->assertSame('bar_baz-bank', $this->uri->param('foo')); } public function testFragment()