Skip to content

Commit

Permalink
Fixed issue where query string could override some parts of the url
Browse files Browse the repository at this point in the history
when using the paginator helper
  • Loading branch information
lorenzo committed Feb 21, 2016
1 parent aab06c6 commit 52f8866
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 20 deletions.
8 changes: 4 additions & 4 deletions src/Routing/Route/Route.php
Expand Up @@ -441,7 +441,9 @@ public function match(array $url, array $context = [])
if (!isset($hostOptions['_base']) && isset($context['_base'])) {
$hostOptions['_base'] = $context['_base'];
}
unset($url['_host'], $url['_scheme'], $url['_port'], $url['_base']);

$query = !empty($url['?']) ? (array)$url['?'] : [];
unset($url['_host'], $url['_scheme'], $url['_port'], $url['_base'], $url['?']);

// Move extension into the hostOptions so its not part of
// reverse matches.
Expand Down Expand Up @@ -484,8 +486,6 @@ public function match(array $url, array $context = [])
}

$pass = [];
$query = [];

foreach ($url as $key => $value) {
// keys that exist in the defaults and have different values is a match failure.
$defaultExists = array_key_exists($key, $defaults);
Expand Down Expand Up @@ -615,7 +615,7 @@ protected function _writeUrl($params, $pass = [], $query = [])
$out .= '.' . $params['_ext'];
}
if (!empty($query)) {
$out .= '?' . http_build_query($query);
$out .= rtrim('?' . http_build_query($query), '?');
}
return $out;
}
Expand Down
6 changes: 0 additions & 6 deletions src/Routing/Router.php
Expand Up @@ -576,12 +576,6 @@ public static function url($url = null, $full = false)
$full = true;
unset($url['_full']);
}
// Compatibility for older versions.
if (isset($url['?'])) {
$q = $url['?'];
unset($url['?']);
$url = array_merge($url, $q);
}
if (isset($url['#'])) {
$frag = '#' . $url['#'];
unset($url['#']);
Expand Down
4 changes: 3 additions & 1 deletion src/View/Helper/PaginatorHelper.php
Expand Up @@ -98,9 +98,11 @@ public function __construct(View $View, array $config = [])
{
parent::__construct($View, $config);

$query = $this->request->query;
unset($query['page'], $query['limit'], $query['sort'], $query['direction']);
$this->config(
'options.url',
array_merge($this->request->params['pass'], $this->request->query)
array_merge($this->request->params['pass'], ['?' => $query])
);
}

Expand Down
19 changes: 19 additions & 0 deletions tests/TestCase/Routing/RouterTest.php
Expand Up @@ -2932,6 +2932,25 @@ public function testDefaultRouteClass()
$this->assertEquals('/foo-bar', $result);
}

/**
* Test generation of routes with collisions between the query string
* and other url params
*
* @return void
*/
public function testUrlWithCollidingQueryString()
{
Router::connect('/:controller/:action/:id');

$query = ['controller' => 'Foo', 'action' => 'bar', 'id' => 100];
$result = Router::url(['controller' => 'posts', 'action' => 'view', 'id' => 1, '?' => $query]);
$this->assertEquals('/posts/view/1?controller=Foo&action=bar&id=100', $result);

$query = ['_host' => 'foo.bar' , '_ssl' => 0, '_scheme' => 'ftp://', '_base' => 'baz', '_port' => '15'];
$result = Router::url(['controller' => 'posts', 'action' => 'view', 'id' => 1, '?' => $query]);
$this->assertEquals('/posts/view/1?_host=foo.bar&_ssl=0&_scheme=ftp%3A%2F%2F&_base=baz&_port=15', $result);
}

/**
* Connect some fallback routes for testing router behavior.
*
Expand Down
16 changes: 8 additions & 8 deletions tests/TestCase/View/Helper/PaginatorHelperTest.php
Expand Up @@ -799,7 +799,7 @@ public function testPassedArgsMergingWithUrlOptions()
];

$this->Paginator->request->params['pass'] = [2];
$this->Paginator->request->query = ['page' => 1, 'foo' => 'bar', 'x' => 'y', 'num' => 0, 'empty' => ''];
$this->Paginator->request->query = ['page' => 1, 'foo' => 'bar', 'x' => 'y', 'num' => 0];
$this->View->request = $this->Paginator->request;
$this->Paginator = new PaginatorHelper($this->View);

Expand All @@ -814,19 +814,19 @@ public function testPassedArgsMergingWithUrlOptions()
$result = $this->Paginator->numbers();
$expected = [
['li' => ['class' => 'active']], '<a href=""', '1', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?page=2&amp;foo=bar&amp;x=y&amp;num=0']], '2', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?page=3&amp;foo=bar&amp;x=y&amp;num=0']], '3', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?page=4&amp;foo=bar&amp;x=y&amp;num=0']], '4', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?page=5&amp;foo=bar&amp;x=y&amp;num=0']], '5', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?page=6&amp;foo=bar&amp;x=y&amp;num=0']], '6', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?page=7&amp;foo=bar&amp;x=y&amp;num=0']], '7', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?foo=bar&amp;x=y&amp;num=0&amp;page=2']], '2', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?foo=bar&amp;x=y&amp;num=0&amp;page=3']], '3', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?foo=bar&amp;x=y&amp;num=0&amp;page=4']], '4', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?foo=bar&amp;x=y&amp;num=0&amp;page=5']], '5', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?foo=bar&amp;x=y&amp;num=0&amp;page=6']], '6', '/a', '/li',
['li' => []], ['a' => ['href' => '/articles/index/2?foo=bar&amp;x=y&amp;num=0&amp;page=7']], '7', '/a', '/li',
];
$this->assertHtml($expected, $result);

$result = $this->Paginator->next('Next');
$expected = [
'li' => ['class' => 'next'],
'a' => ['href' => '/articles/index/2?page=2&amp;foo=bar&amp;x=y&amp;num=0', 'rel' => 'next'],
'a' => ['href' => '/articles/index/2?foo=bar&amp;x=y&amp;num=0&amp;page=2', 'rel' => 'next'],
'Next',
'/a',
'/li'
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/View/Helper/UrlHelperTest.php
Expand Up @@ -97,7 +97,7 @@ public function testUrlConversion()
'controller' => 'posts', 'action' => 'index', 'page' => '1',
'?' => ['one' => 'value', 'two' => 'value', 'three' => 'purple']
]);
$this->assertEquals("/posts/index?page=1&amp;one=value&amp;two=value&amp;three=purple", $result);
$this->assertEquals("/posts/index?one=value&amp;two=value&amp;three=purple&amp;page=1", $result);
}

/**
Expand Down

0 comments on commit 52f8866

Please sign in to comment.